From c68cbf162532364e16fd28a1a6fb35d141e2d82e Mon Sep 17 00:00:00 2001 From: Alex Buts Date: Thu, 5 Dec 2013 11:10:29 +0000 Subject: [PATCH 001/118] refs #8557 Two questions to 2 suspicious places of code Two places found after code review which look like wrong. Questions to code were placed after //!!! mark --- .../WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp | 1 + Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp index 8d579954c8a0..de7149c3d4b8 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsProcessDetectorVanadium.cpp @@ -147,6 +147,7 @@ namespace Mantid // Mask and group workspace if necessary. MatrixWorkspace_sptr maskWS = this->getProperty("MaskWorkspace"); +//!!! I see masks here but where is the map workspace used for vanadium grouping (In ISIS)? IAlgorithm_sptr remap = this->createChildAlgorithm("DgsRemap"); remap->setProperty("InputWorkspace", outputWS); remap->setProperty("OutputWorkspace", outputWS); diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp index 40a4f85b0299..9b3aca8056ef 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/DgsReduction.cpp @@ -815,6 +815,7 @@ namespace Mantid absUnitsRed->setProperty("OutputWorkspace", absWsName); absUnitsRed->executeAsChildAlg(); MatrixWorkspace_sptr absUnitsWS = absUnitsRed->getProperty("OutputWorkspace"); +//!!! There is Property outputMaskWorkspace to get masks? It looks like one is using wrong property for masks MatrixWorkspace_sptr absMaskWS = absUnitsRed->getProperty("OutputWorkspace"); IAlgorithm_sptr mask = this->createChildAlgorithm("MaskDetectors"); From 2f78d54c5a5cc3db89aecb781fe02a636532d6cd Mon Sep 17 00:00:00 2001 From: Samuel Jackson Date: Mon, 10 Feb 2014 18:12:35 +0000 Subject: [PATCH 002/118] Refs #8281 Tidy up the S(Q,w) interface on C2E. --- .../ConvertToEnergy.ui | 809 ++++++++---------- 1 file changed, 339 insertions(+), 470 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui index 16cb8de86c1d..effe589d8cb9 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui @@ -56,7 +56,7 @@ - + TOF Direct Geometry Spectroscopy TOF Indirect Geometry Spectroscopy @@ -172,7 +172,7 @@ 6 - + Runs @@ -188,7 +188,7 @@ - + false @@ -207,7 +207,7 @@ - + Detector Vanadium @@ -228,7 +228,7 @@ - + 0 @@ -244,7 +244,7 @@ - + false @@ -266,7 +266,7 @@ true - + _calib.nxs @@ -375,7 +375,7 @@ - + 0 @@ -394,7 +394,7 @@ - + .map @@ -1720,7 +1720,7 @@ Later steps in the process (saving, renaming) will not be done. - + 0 @@ -1736,7 +1736,7 @@ Later steps in the process (saving, renaming) will not be done. - + .raw @@ -2021,7 +2021,7 @@ Later steps in the process (saving, renaming) will not be done. - + 0 @@ -2037,7 +2037,7 @@ Later steps in the process (saving, renaming) will not be done. true - + .raw @@ -2063,7 +2063,7 @@ Later steps in the process (saving, renaming) will not be done. - + false @@ -2085,7 +2085,7 @@ Later steps in the process (saving, renaming) will not be done. true - + _calib.nxs @@ -2158,11 +2158,11 @@ Later steps in the process (saving, renaming) will not be done. - + - + .raw @@ -2170,11 +2170,11 @@ Later steps in the process (saving, renaming) will not be done. - + - + .raw @@ -2270,7 +2270,7 @@ Later steps in the process (saving, renaming) will not be done. S(Q, w) - + @@ -2284,155 +2284,30 @@ Later steps in the process (saving, renaming) will not be done. - - - - - Input Type - - - - - - - true - - - - File - - - - - Workspace - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - 0 - - - - - - - - 0 - 41 - - - - false - - - Input File - - - false - - - - - - - _red.nxs - - - - - - - - - - - - - - - 0 - 41 - - - - Workspace: - - - - - - - - 0 - 0 - - - - - - - - _red - - - - - - - - - 0 - 41 - - - - color: rgb(255, 0, 4) - - - * - - - - - - - - - - - - - Plot Input - - - - + + + + 0 + 0 + + + + false + + + Plot Input + + + + _red + + + + + _red.nxs + + + @@ -2442,319 +2317,313 @@ Later steps in the process (saving, renaming) will not be done. Options - + - - - + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 16777215 + 16777215 + + + + 0 + - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Rebin Type</span></p></body></html> - - + + Centre (SofQW) + - - - - 0 - 0 - - - - - 150 - 0 - - - - - 16777215 - 16777215 - - - - 0 - - - - Centre (SofQW) - - - - - Parallelepiped (SofQW2) - - - - - Parallelepiped/Fractional Area (SofQW3) - - - + + Parallelepiped (SofQW2) + - - - Qt::Horizontal - - - - 40 - 20 - - - + + Parallelepiped/Fractional Area (SofQW3) + - + + + + + + false + + + + 0 + 0 + + + + + 60 + 16777215 + + + + + + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + + 43 + 0 + + + + E Width: + + + + + + + + 43 + 0 + + + + Q Width: + + + + + + + false + + + + 0 + 0 + + + + + 60 + 16777215 + + + + + + + + false + + + color: rgb(255, 0, 4) + + + + + + + + + + false + + + + 43 + 0 + + + + E High: + + + + + + + false + + + color: rgb(255, 0, 4) + + + + + + + + + + false + + + color: rgb(255, 0, 4) + + + + + + + + + + Rebin Type: + + + + + + + + 0 + 0 + + + + + + + + color: rgb(255, 0, 4) + + + * + + - - - - - - - 43 - 0 - - - - Q Low: - - - - - - - - - - color: rgb(255, 0, 4) - - - * - - - - + + + + color: rgb(255, 0, 4) + + + * + + - - - - - - - 43 - 0 - - - - Q Width: - - - - - - - - - - color: rgb(255, 0, 4) - - - * - - - - + + + + + 43 + 0 + + + + Q Low: + + - - - - - - - 43 - 0 - - - - Q High: - - - - - - - - - - color: rgb(255, 0, 4) - - - * - - - - + + + + + 0 + 0 + + + - - - - - - 10 - - - 10 - - - - - - - - - 1 + + + + color: rgb(255, 0, 4) - - 2 + + * - - - - Rebin in Energy - - - - + - - - - - - false - - - - 43 - 0 - - - - E Low: - - - - - - - false - - - - - - - false - - - color: rgb(255, 0, 4) - - - - - - - + + + + + 43 + 0 + + + + Q High: + + - - - - - - false - - - - 43 - 0 - - - - E Width: - - - - - - - false - - - - - - - false - - - color: rgb(255, 0, 4) - - - - - - - + + + + false + + + + 0 + 0 + + + + + 60 + 16777215 + + + - - - - - - false - - - - 43 - 0 - - - - E High: - - - - - - - false - - - - - - - false - - - color: rgb(255, 0, 4) - - - - - - - + + + + Rebin in Energy + + + + + + + false + + + + 43 + 0 + + + + E Low: + + @@ -2934,14 +2803,14 @@ p, li { white-space: pre-wrap; } - + Abs Units Vanadium - + false @@ -2960,7 +2829,7 @@ p, li { white-space: pre-wrap; } - + Detector Vanadium (Abs Units) @@ -3364,9 +3233,9 @@ p, li { white-space: pre-wrap; }
MantidQtMantidWidgets/InstrumentSelector.h
- MantidQt::MantidWidgets::WorkspaceSelector - QComboBox -
MantidQtMantidWidgets/WorkspaceSelector.h
+ MantidQt::MantidWidgets::DataSelector + QWidget +
MantidQtMantidWidgets/DataSelector.h
From 34eff7209ab47cede4f72e684a3ce35a81efdba1 Mon Sep 17 00:00:00 2001 From: Samuel Jackson Date: Mon, 10 Feb 2014 18:12:59 +0000 Subject: [PATCH 003/118] Refs #8281 Hook up data selector widget to interface. --- .../CustomInterfaces/src/Indirect.cpp | 97 ++++++++----------- 1 file changed, 42 insertions(+), 55 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect.cpp index a0f224ed15cb..aef686160a29 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect.cpp @@ -104,10 +104,7 @@ void Indirect::initLayout() // "SofQW" tab connect(m_uiForm.sqw_ckRebinE, SIGNAL(toggled(bool)), this, SLOT(sOfQwRebinE(bool))); - connect(m_uiForm.sqw_cbInput, SIGNAL(currentIndexChanged(int)), m_uiForm.sqw_swInput, SLOT(setCurrentIndex(int))); - connect(m_uiForm.sqw_cbWorkspace, SIGNAL(currentIndexChanged(int)), this, SLOT(validateSofQ(int))); - - connect(m_uiForm.sqw_pbPlotInput, SIGNAL(clicked()), this, SLOT(sOfQwPlotInput())); + connect(m_uiForm.sqw_dsSampleInput, SIGNAL(loadClicked()), this, SLOT(sOfQwPlotInput())); // "Slice" tab connect(m_uiForm.slice_inputFile, SIGNAL(filesFound()), this, SLOT(slicePlotRaw())); @@ -840,24 +837,15 @@ bool Indirect::validateSofQw() { bool valid = true; - if ( m_uiForm.sqw_cbInput->currentText() == "File" ) - { - if ( ! m_uiForm.sqw_inputFile->isValid() ) - { - valid = false; - } - } - else + + UserInputValidator uiv; + uiv.checkDataSelectorIsValid("Sample", m_uiForm.sqw_dsSampleInput); + QString error = uiv.generateErrorMessage(); + + if (!error.isEmpty()) { - if ( m_uiForm.sqw_cbWorkspace->currentText().isEmpty() ) - { - valid = false; - m_uiForm.sqw_valWorkspace->setText("*"); - } - else - { - m_uiForm.sqw_valWorkspace->setText(" "); - } + valid = false; + showInformationBox(error); } if ( m_uiForm.sqw_ckRebinE->isChecked() ) @@ -972,7 +960,7 @@ void Indirect::loadSettings() m_uiForm.ind_calibFile->readSettings(settings.group()); m_uiForm.ind_mapFile->readSettings(settings.group()); m_uiForm.slice_calibFile->readSettings(settings.group()); - m_uiForm.sqw_inputFile->readSettings(settings.group()); + m_uiForm.sqw_dsSampleInput->readSettings(settings.group()); settings.endGroup(); } @@ -1781,18 +1769,19 @@ void Indirect::sOfQwClicked() QString rebinString = m_uiForm.sqw_leQLow->text()+","+m_uiForm.sqw_leQWidth->text()+","+m_uiForm.sqw_leQHigh->text(); QString pyInput = "from mantid.simpleapi import *\n"; - if ( m_uiForm.sqw_cbInput->currentText() == "File" ) + switch(m_uiForm.sqw_dsSampleInput->getCurrentView()) { - pyInput += - "filename = r'" +m_uiForm.sqw_inputFile->getFirstFilename() + "'\n" - "(dir, file) = os.path.split(filename)\n" - "(sqwInput, ext) = os.path.splitext(file)\n" - "LoadNexus(Filename=filename, OutputWorkspace=sqwInput)\n"; - } - else - { - pyInput += - "sqwInput = '" + m_uiForm.sqw_cbWorkspace->currentText() + "'\n"; + case 0: + //load the file + pyInput += "filename = r'" + m_uiForm.sqw_dsSampleInput->getFullFilePath() + "'\n" + "(dir, file) = os.path.split(filename)\n" + "(sqwInput, ext) = os.path.splitext(file)\n" + "LoadNexus(Filename=filename, OutputWorkspace=sqwInput)\n"; + break; + case 1: + //get the workspace + pyInput += "sqwInput = '" + m_uiForm.sqw_dsSampleInput->getCurrentDataName() + "'\n"; + break; } // Create output name before rebinning @@ -1866,35 +1855,33 @@ void Indirect::sOfQwPlotInput() QString pyInput = "from mantid.simpleapi import *\n" "from mantidplot import *\n"; - //... - if ( m_uiForm.sqw_cbInput->currentText() == "File" ) + if (m_uiForm.sqw_dsSampleInput->isValid()) { - // get filename - if ( m_uiForm.sqw_inputFile->isValid() ) + switch(m_uiForm.sqw_dsSampleInput->getCurrentView()) { - pyInput += - "filename = r'" + m_uiForm.sqw_inputFile->getFirstFilename() + "'\n" - "(dir, file) = os.path.split(filename)\n" - "(input, ext) = os.path.splitext(file)\n" - "LoadNexus(Filename=filename, OutputWorkspace=input)\n"; - } - else - { - showInformationBox("Invalid filename."); - return; + case 0: + //load the file + pyInput += "filename = r'" + m_uiForm.sqw_dsSampleInput->getFullFilePath() + "'\n" + "(dir, file) = os.path.split(filename)\n" + "(sqwInput, ext) = os.path.splitext(file)\n" + "LoadNexus(Filename=filename, OutputWorkspace=sqwInput)\n"; + break; + case 1: + //get the workspace + pyInput += "sqwInput = '" + m_uiForm.sqw_dsSampleInput->getCurrentDataName() + "'\n"; + break; } + + pyInput += "ConvertSpectrumAxis(InputWorkspace=sqwInput, OutputWorkspace=sqwInput[:-4]+'_rqw', Target='ElasticQ', EMode='Indirect')\n" + "ws = importMatrixWorkspace(sqwInput[:-4]+'_rqw')\n" + "ws.plotGraph2D()\n"; + + QString pyOutput = runPythonCode(pyInput).trimmed(); } else { - pyInput += "input = '" + m_uiForm.sqw_cbWorkspace->currentText() + "'\n"; + showInformationBox("Invalid filename."); } - - pyInput += "ConvertSpectrumAxis(InputWorkspace=input, OutputWorkspace=input[:-4]+'_rqw', Target='ElasticQ', EMode='Indirect')\n" - "ws = importMatrixWorkspace(input[:-4]+'_rqw')\n" - "ws.plotGraph2D()\n"; - - QString pyOutput = runPythonCode(pyInput).trimmed(); - } // SLICE From 8f7ddc3d6b02682ec147be54215556dce67f211c Mon Sep 17 00:00:00 2001 From: Samuel Jackson Date: Tue, 11 Feb 2014 14:03:22 +0000 Subject: [PATCH 004/118] Refs #8281 Fix tab order for binning input on S(Q,w) interface. --- .../ConvertToEnergy.ui | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui index effe589d8cb9..6813abc1114c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui @@ -3277,6 +3277,65 @@ Later steps in the process (saving, renaming) will not be done. leVanMass leSamMass leRMMMass + cbInst + runFiles + mapFile + whiteBeamFile + ind_runFiles + ind_calibFile + ckLoadLogs + ind_mapFile + ckDetailedBalance + leDetailedBalance + ckScaleMultiplier + leScaleMultiplier + motorNameEdit + seOffsetEdit + cbIndRebType + leRebinString + save_ckNxSPE + save_ckAscii + save_ckAclimax + ckVerbose + ckCreateInfoTable + ind_cbPlotOutput + ckRenameWorkspace + ckFold + ckCm1Units + cal_leRunNo + cal_pbPlot + cal_ckIntensityScaleMultiplier + cal_leIntensityScaleMultiplier + cal_ckResScale + cal_leResScale + cal_ckRES + cal_ckPlotResult + slice_inputFile + slice_pbPlotRaw + slice_ckUseCalib + slice_calibFile + slice_ckVerbose + slice_ckPlot + slice_ckSave + transInputFile + transCanFile + trans_ckVerbose + trans_ckPlot + trans_ckSave + sqw_cbRebinType + sqw_leELow + sqw_leEWidth + sqw_leEHigh + sqw_leQLow + sqw_leQWidth + sqw_leQHigh + sqw_ckRebinE + sqw_cbPlotType + sqw_ckSave + absRunFiles + absMapFile + absWhiteFile + pbManageDirectories From e73c6e52740735dba1e7b0c54889df2020b91005 Mon Sep 17 00:00:00 2001 From: Jose Borreguero Date: Tue, 11 Feb 2014 10:28:21 -0500 Subject: [PATCH 005/118] Refs #8991 Header removed --- Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp b/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp index 6cb96bd1aaaa..624c54134597 100644 --- a/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SassenaFFT.cpp @@ -26,7 +26,6 @@ Below are plots after application of SassenaFFT to I(Q,t) = e^{-t^2/(2\sig // Includes //---------------------------------------------------------------------- #include "MantidAlgorithms/SassenaFFT.h" -#include "MantidKernel/VisibleWhenProperty.h" #include "MantidKernel/EnabledWhenProperty.h" #include "MantidKernel/UnitFactory.h" #include "MantidDataObjects/Workspace2D.h" From 4c40ddbf98325c3d461bbe764e2d870ce708975a Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:10:05 +0000 Subject: [PATCH 006/118] re #9014: Bring Reducer and ReductionSingleton to SANS folder --- Code/Mantid/scripts/SANS/reducer_singleton.py | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 Code/Mantid/scripts/SANS/reducer_singleton.py diff --git a/Code/Mantid/scripts/SANS/reducer_singleton.py b/Code/Mantid/scripts/SANS/reducer_singleton.py new file mode 100644 index 000000000000..76ff6f018273 --- /dev/null +++ b/Code/Mantid/scripts/SANS/reducer_singleton.py @@ -0,0 +1,186 @@ +import random +import string +import os +import mantid + +from isis_instrument import BaseInstrument + +class Reducer(object): + """ + Base reducer class. Instrument-specific reduction processes should be + implemented in a child of this class. + """ + + ## Instrument configuration object + instrument = None + ## Path for data files + _data_path = '.' + ## Path for output files + _output_path = None + ## List of reduction steps + _reduction_steps = [] + ## Log + log_text = '' + ## Output workspaces + output_workspaces = [] + + def __init__(self): + self.UID = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(5)) + self._reduction_steps = [] + + def set_instrument(self, configuration): + if issubclass(configuration.__class__, BaseInstrument): + self.instrument = configuration + else: + raise RuntimeError, "Reducer.set_instrument expects an %s object, found %s" % (Instrument, configuration.__class__) + + def set_data_path(self, path): + """ + Set the path for data files + @param path: data file path + """ + path = os.path.normcase(path) + if os.path.isdir(path): + self._data_path = path + mantid.config.appendDataSearchDir(path) + else: + raise RuntimeError, "Reducer.set_data_path: provided path is not a directory (%s)" % path + + def set_output_path(self, path): + """ + Set the path for output files + @param path: output file path + """ + path = os.path.normcase(path) + if os.path.isdir(path): + self._output_path = path + else: + raise RuntimeError, "Reducer.set_output_path: provided path is not a directory (%s)" % path + + def pre_process(self): + """ + Reduction steps that are meant to be executed only once per set + of data files. After this is executed, all files will go through + the list of reduction steps. + """ + pass + + def post_process(self): + """ + Reduction steps to be executed after all data files have been + processed. + """ + pass + + def reduce(self): + """ + Go through the list of reduction steps + """ + # should we use it? + t_0 = time.time() + instrument_name = '' + self.output_workspaces = [] + + # Check that an instrument was specified + if self.instrument is not None: + instrument_name = self.instrument.name() + + # Log text + self.log_text = "%s reduction - %s\n" % (instrument_name, time.ctime()) + + # Go through the list of steps that are common to all data files + self.pre_process() + + # Go through the list of files to be reduced + #for file_ws in self._data_files: + # for item in self._reduction_steps: + # try: + # result = item.execute(self, file_ws) + # if result is not None and len(str(result))>0: + # self.log_text += "%s\n" % str(result) + # except: + # self.log_text += "\n%s\n" % sys.exc_value + # raise + + #any clean up, possibly removing workspaces + self.post_process() + + # Determine which directory to use + output_dir = self._data_path + if self._output_path is not None: + if os.path.isdir(self._output_path): + output_dir = self._output_path + else: + output_dir = os.path.expanduser('~') + + self.log_text += "Reduction completed in %g sec\n" % (time.time()-t_0) + log_path = os.path.join(output_dir,"%s_reduction.log" % instrument_name) + self.log_text += "Log saved to %s" % log_path + + # Write the log to file + f = open(log_path, 'a') + f.write("\n-------------------------------------------\n") + f.write(self.log_text) + f.close() + return self.log_text + + + + +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) + From a61bbcd1318553599741f0f771b6600d03fbc587 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:11:35 +0000 Subject: [PATCH 007/118] re #9014: Bring reduction steps to sans_reduction_steps While moving, I've tried to remove those methods and attributes that we were not using at all. It might have more, which must be investigated in another opportunity. --- .../scripts/SANS/isis_reduction_steps.py | 589 ++++++++++++++++-- 1 file changed, 539 insertions(+), 50 deletions(-) diff --git a/Code/Mantid/scripts/SANS/isis_reduction_steps.py b/Code/Mantid/scripts/SANS/isis_reduction_steps.py index 7b2db23af834..295fbee56d52 100644 --- a/Code/Mantid/scripts/SANS/isis_reduction_steps.py +++ b/Code/Mantid/scripts/SANS/isis_reduction_steps.py @@ -6,10 +6,9 @@ Most of this code is a copy-paste from SANSReduction.py, organized to be used with ReductionStep objects. The guts needs refactoring. """ -from reduction import ReductionStep import isis_reducer -import reduction.instruments.sans.sans_reduction_steps as sans_reduction_steps -sanslog = sans_reduction_steps.sanslog +from mantid.kernel import Logger +sanslog = Logger.get("SANS") from mantid.simpleapi import * from mantid.api import WorkspaceGroup, Workspace, IEventWorkspace @@ -22,6 +21,8 @@ import math import copy import re +import random +import string def _issueWarning(msg): """ @@ -40,6 +41,36 @@ def _issueInfo(msg): sanslog.notice(msg) +class ReductionStep(object): + """ + Base class for reduction steps + """ + @classmethod + def delete_workspaces(cls, workspace): + """ + Delete all workspace created by this reduction step related + to the given workspace + @param workspace: workspace to delete + """ + return + + @classmethod + def _create_unique_name(cls, filepath, descriptor): + """ + Generate a unique name for an internal workspace + """ + random_str = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(5)) + return "__"+descriptor+"_"+extract_workspace_name(filepath)+"_"+random_str + + def execute(self, reducer, inputworkspace=None, outputworkspace=None): + """ + Implemented the reduction step. + @param reducer: Reducer object for which the step is executed + @param inputworkspace: Name of the workspace to apply this step to + @param outputworkspace: Name of the workspace to have as an output. If this is None it will be set to inputworkspace + """ + raise NotImplemented + class LoadRun(object): UNSET_PERIOD = -1 def __init__(self, run_spec=None, trans=False, reload=True, entry=UNSET_PERIOD): @@ -412,7 +443,7 @@ def execute(self, reducer, workspace): #clean up the workspaces ready users to see them if required if reducer.to_Q.output_type == '1D': - rem_nans = sans_reduction_steps.StripEndNans() + rem_nans = StripEndNans() self._keep_partial_results(tmp_smp, tmp_can) @@ -437,14 +468,22 @@ def _keep_partial_results(self, sample_name, can_name): periods_in_file = property(get_periods_in_file, None, None, None) -class Mask_ISIS(sans_reduction_steps.Mask): +class Mask_ISIS(ReductionStep): """ + Marks some spectra so that they are not included in the analysis Provides ISIS specific mask functionality (e.g. parsing MASK commands from user files), inherits from Mask """ def __init__(self, timemask='', timemask_r='', timemask_f='', specmask='', specmask_r='', specmask_f=''): - sans_reduction_steps.Mask.__init__(self) + self._xml = [] + + #these spectra will be masked by the algorithm MaskDetectors + self.detect_list = [] + + # List of pixels to mask + self.masked_pixels = [] + self.time_mask=timemask self.time_mask_r=timemask_r self.time_mask_f=timemask_f @@ -483,6 +522,73 @@ def __init__(self, timemask='', timemask_r='', timemask_f='', self.min_radius = None self.max_radius = None + def add_xml_shape(self, complete_xml_element): + """ + Add an arbitrary shape to region to be masked + @param complete_xml_element: description of the shape to add + """ + if not complete_xml_element.startswith('<') : + raise ValueError('Excepted xml string but found: ' + str(complete_xml_element)) + self._xml.append(complete_xml_element) + + def _infinite_plane(self, id, plane_pt, normal_pt, complement = False): + """ + Generates xml code for an infinte plane + @param id: a string to refer to the shape by + @param plane_pt: a point in the plane + @param normal_pt: the direction of a normal to the plane + @param complement: mask in the direction of the normal or away + @return the xml string + """ + if complement: + addition = '#' + else: + addition = '' + return '' + \ + '' + \ + ''+ \ + '\n' + + def _infinite_cylinder(self, centre, radius, axis, id='shape'): + """ + Generates xml code for an infintely long cylinder + @param centre: a tupple for a point on the axis + @param radius: cylinder radius + @param axis: cylinder orientation + @param id: a string to refer to the shape by + @return the xml string + """ + return '' + \ + '' + \ + '' + \ + '\n' + + def _finite_cylinder(self, centre, radius, height, axis, id='shape'): + """ + Generates xml code for an infintely long cylinder + @param centre: a tupple for a point on the axis + @param radius: cylinder radius + @param height: cylinder height + @param axis: cylinder orientation + @param id: a string to refer to the shape by + @return the xml string + """ + return '' + \ + '' + \ + '' + \ + '\n' + + def add_cylinder(self, radius, xcentre, ycentre, ID='shape'): + '''Mask the inside of an infinite cylinder on the input workspace.''' + self.add_xml_shape( + self._infinite_cylinder([xcentre, ycentre, 0.0], radius, [0,0,1], id=ID)+'') + + + def add_outside_cylinder(self, radius, xcentre = 0.0, ycentre = 0.0, ID='shape'): + '''Mask out the outside of a cylinder or specified radius''' + self.add_xml_shape( + self._infinite_cylinder([xcentre, ycentre, 0.0], radius, [0,0,1], id=ID)+'') + def set_radi(self, min, max): self.min_radius = float(min)/1000. self.max_radius = float(max)/1000. @@ -757,15 +863,6 @@ def get_phi_limits_tag(self): else: return '' - def normalizePhi(self, phi): - if phi > 90.0: - phi -= 180.0 - elif phi < -90.0: - phi += 180.0 - else: - pass - return phi - def set_phi_limit(self, phimin, phimax, phimirror, override=True): ''' ... (tx to Richard for changes to this function @@ -826,7 +923,8 @@ def execute(self, reducer, workspace): if ( not self.max_radius is None ) and ( self.max_radius > 0.0 ): self.add_outside_cylinder(self.max_radius, 0, 0, 'beam_area') #now do the masking - sans_reduction_steps.Mask.execute(self, reducer, workspace) + for shape in self._xml: + MaskDetectorsInShape(Workspace=workspace, ShapeXML=shape) if len(self.spec_list)>0: MaskDetectors(Workspace=workspace, SpectraList = self.spec_list) @@ -843,6 +941,9 @@ def execute(self, reducer, workspace): MaskDetectorsInShape(Workspace=workspace,ShapeXML= self._mask_line(start_point, 1e6, self.arm_width, self.arm_angle)) + output_ws, detector_list = ExtractMask(InputWorkspace=workspace, OutputWorkspace="__mask") + _issueInfo("Mask check %s: %g masked pixels" % (workspace, len(detector_list))) + def view(self, instrum): """ In MantidPlot this opens InstrumentView to display the masked @@ -929,8 +1030,7 @@ def display(self, wksp, reducer, counts=None): Multiply(LHSWorkspace='ones',RHSWorkspace= wksp,OutputWorkspace= 'units') #do the super-position and clean up Minus(LHSWorkspace=counts,RHSWorkspace= 'units',OutputWorkspace= wksp) - DeleteWorkspace('ones') - DeleteWorkspace('units') + reducer.deleteWorkspaces(['ones', 'units']) #opens an instrument showing the contents of the workspace (i.e. the instrument with masked detectors) instrum.view(wksp) @@ -1308,16 +1408,19 @@ def calculate(self, reducer): OutputUnfittedData=True, **options) # options FitMethod, PolynomialOrder if present # Remove temporaries - DeleteWorkspace(Workspace=trans_tmp_out) + files2delete = [trans_tmp_out] + if direct_tmp_out != trans_tmp_out: - DeleteWorkspace(Workspace=direct_tmp_out) + files2delete.append(direct_tmp_out) if sel_settings[FITMETHOD] in ['OFF', 'CLEAR']: result = unfittedtransws - DeleteWorkspace(fittedtransws) + files2delete.append(fittedtransws) else: result = fittedtransws + reducer.deleteWorkspaces(files2delete) + return result def get_trans_spec(self): @@ -1380,18 +1483,23 @@ def execute(self, reducer, workspace): ws = mtd[workspace] ws *= scalefactor -class CalculateNormISIS(sans_reduction_steps.CalculateNorm): + +class CalculateNormISIS(object): """ - Note this is not a reduction step, see sans_reduction_steps.CalculateNorm + Note this is not a reduction step, see CalculateNorm Generates the normalization workspaces required by Q1D and Qxy for normalization produced by other, sometimes optional, reduction_steps or a specified workspace """ TMP_ISIS_NAME = '__CalculateNormISIS_loaded_tmp' - + TMP_WORKSPACE_NAME = '__CalculateNorm_loaded_temp' + WAVE_CORR_NAME = '__Q_WAVE_conversion_temp' + PIXEL_CORR_NAME = '__Q_pixel_conversion_temp' + def __init__(self, wavelength_deps=[]): - super(CalculateNormISIS, self).__init__(wavelength_deps) + super(CalculateNormISIS, self).__init__() + self._wave_steps = wavelength_deps #algorithm to be used to load pixel correction files self._load='LoadRKH' #a parameters string to add as the last argument to the above algorithm @@ -1407,8 +1515,6 @@ def setPixelCorrFile(self, filename, detector = ""): but, now, we need pixel_file (flood file) for both detectors. so, an extra parameter is allowed. - override CalculateNorm. - """ detector = detector.upper() @@ -1423,7 +1529,6 @@ def getPixelCorrFile(self, detector ): but, now, we need pixel_file (flood file) for both detectors. so, an extra parameter is allowed. - override CalculateNorm. """ detector = detector.upper() if detector in ("FRONT","HAB","FRONT-DETECTOR-BANK", "FRONT-DETECTOR"): @@ -1434,6 +1539,51 @@ def getPixelCorrFile(self, detector ): logger.warning("Request of pixel correction file with unknown detector ("+ str(detector)+")") return self._pixel_file + + def _multiplyAll(self, wave_wksps, wksp2match): + wave_adj = None + for wksp in wave_wksps: + #before the workspaces can be combined they all need to match + RebinToWorkspace(WorkspaceToRebin=wksp, WorkspaceToMatch=wksp2match, + OutputWorkspace=self.TMP_WORKSPACE_NAME) + + if not wave_adj: + wave_adj = self.WAVE_CORR_NAME + RenameWorkspace(InputWorkspace=self.TMP_WORKSPACE_NAME, OutputWorkspace=wave_adj) + else: + Multiply(LHSWorkspace=self.TMP_WORKSPACE_NAME, RHSWorkspace=wave_adj, + OutputWorkspace= wave_adj) + return wave_adj + + def _loadPixelCorrection(self): + # read pixel correction file + # note the python code below is an attempt to emulate function overloading + # If a derived class overwrite self._load and self._load_params then + # a custom specific loading can be achieved + pixel_adj = '' + if self._pixel_file: + pixel_adj = self.PIXEL_CORR_NAME + load_com = self._load+'(Filename="'+self._pixel_file+'",OutputWorkspace="'+pixel_adj+'"' + if self._load_params: + load_com += ','+self._load_params + load_com += ')' + eval(load_com) + + return pixel_adj + + def _is_point_data(self, wksp): + """ + Tests if the workspace whose name is passed contains point or histogram data + The test is if the X and Y array lengths are the same = True, different = false + @param wksp: name of the workspace to test + @return True for point data, false for histogram + """ + handle = mtd[wksp] + if len(handle.readX(0)) == len(handle.readY(0)): + return True + else: + return False + def calculate(self, reducer, wave_wks=[]): """ Multiplies all the wavelength scalings into one workspace and all the detector @@ -1453,26 +1603,98 @@ def calculate(self, reducer, wave_wks=[]): detect_pixel_file = self.getPixelCorrFile(reducer.instrument.cur_detector().name()) if (detect_pixel_file != ""): self._pixel_file = detect_pixel_file - wave_adj, pixel_adj = super(CalculateNormISIS, self).calculate(reducer, wave_wks) + + for step in self._wave_steps: + if step.output_wksp: + wave_wks.append(step.output_wksp) + + wave_adj = self._multiplyAll(wave_wks, reducer.output_wksp) + + pixel_adj = self._loadPixelCorrection() if pixel_adj: #remove all the pixels that are not present in the sample data (the other detector) reducer.instrument.cur_detector().crop_to_detector(pixel_adj, pixel_adj) - isis_reducer.deleteWorkspaces([self.TMP_ISIS_NAME]) + reducer.deleteWorkspaces([self.TMP_ISIS_NAME, self.TMP_WORKSPACE_NAME]) return wave_adj, pixel_adj -class ConvertToQISIS(sans_reduction_steps.ConvertToQ): - """ - Extend the sans_recution_steps.ConvertToQ to use the property WavePixelAdj. +class ConvertToQISIS(ReductionStep): + """ + Runs the Q1D or Qxy algorithms to convert wavelength data into momentum transfer, Q + Currently, this allows the wide angle transmission correction. """ + # the list of possible Q conversion algorithms to use + _OUTPUT_TYPES = {'1D' : 'Q1D', + '2D' : 'Qxy'} + # defines if Q1D should correct for gravity by default + _DEFAULT_GRAV = False + def __init__(self, normalizations): + """ + @param normalizations: CalculateNormISIS object contains the workspace, ReductionSteps or files require for the optional normalization arguments + """ + if not issubclass(normalizations.__class__, CalculateNormISIS): + raise RuntimeError('Error initializing ConvertToQ, invalid normalization object') + #contains the normalization optional workspaces to pass to the Q algorithm + self._norms = normalizations + + #this should be set to 1D or 2D + self._output_type = '1D' + #the algorithm that corresponds to the above choice + self._Q_alg = self._OUTPUT_TYPES[self._output_type] + #if true gravity is taken into account in the Q1D calculation + self._use_gravity = self._DEFAULT_GRAV + #used to implement a default setting for gravity that can be over written but doesn't over write + self._grav_set = False + #this should contain the rebin parameters + self.binning = None + + #The minimum distance in metres from the beam center at which all wavelengths are used in the calculation + self.r_cut = 0.0 + #The shortest wavelength in angstrom at which counts should be summed from all detector pixels in Angstrom + self.w_cut = 0.0 + # Whether to output parts when running either Q1D2 or Qxy + self.outputParts = False + + def set_output_type(self, descript): + """ + Requests the given output from the Q conversion, either 1D or 2D. For + the 1D calculation it asks the reducer to keep a workspace for error + estimates + @param descript: 1D or 2D + """ + self._Q_alg = self._OUTPUT_TYPES[descript] + self._output_type = descript + + def get_output_type(self): + return self._output_type + + output_type = property(get_output_type, set_output_type, None, None) + + def get_gravity(self): + return self._use_gravity + + def set_gravity(self, flag, override=True): + """ + Enable or disable including gravity when calculating Q + @param flag: set to True to enable the gravity correction + @param override: over write the setting from a previous call to this method (default is True) + """ + if override: + self._grav_set = True + + if (not self._grav_set) or override: + self._use_gravity = bool(flag) + else: + msg = "User file can't override previous gravity setting, do gravity correction remains " + str(self._use_gravity) + print msg + sanslog.warning(msg) + def execute(self, reducer, workspace): """ Calculate the normalization workspaces and then call the chosen Q conversion algorithm. - Almost a copy of sans_reduction_steps.ConvertToQ, except by the calculation of - the transmission correction wide angle. """ wavepixeladj = "" if (reducer.wide_angle_correction and reducer.transmission_calculator.output_wksp): @@ -1489,16 +1711,6 @@ def execute(self, reducer, workspace): else: raise RuntimeError('Normalization workspaces must be created by CalculateNorm() and passed to this step') - # If some prenormalization flag is set - normalize data with wave_adj and pixel_adj - if self.prenorm: - data = mtd[workspace] - if wave_adj: - data /= mtd[wave_adj] - if pixel_adj: - data /= mtd[pixel_adj] - self._deleteWorkspaces([wave_adj, pixel_adj]) - wave_adj, pixel_adj = '', '' - try: if self._Q_alg == 'Q1D': Q1D(DetBankWorkspace=workspace,OutputWorkspace= workspace, OutputBinning=self.binning, WavelengthAdj=wave_adj, PixelAdj=pixel_adj, AccountForGravity=self._use_gravity, RadiusCut=self.r_cut*1000.0, WaveCut=self.w_cut, OutputParts=self.outputParts, WavePixelAdj = wavepixeladj) @@ -1509,10 +1721,10 @@ def execute(self, reducer, workspace): raise NotImplementedError('The type of Q reduction has not been set, e.g. 1D or 2D') except: #when we are all up to Python 2.5 replace the duplicated code below with one finally: - self._deleteWorkspaces([wave_adj, pixel_adj, wavepixeladj]) + reducer.deleteWorkspaces([wave_adj, pixel_adj, wavepixeladj]) raise - self._deleteWorkspaces([wave_adj, pixel_adj, wavepixeladj]) + reducer.deleteWorkspaces([wave_adj, pixel_adj, wavepixeladj]) class UnitsConvert(ReductionStep): """ @@ -1631,6 +1843,40 @@ def execute(self, reducer, workspace): self.monitor = '_scaled_monitor' CropWorkspace(hist, EndWorkspaceIndex=_monitor.getNumberHistograms()-1, OutputWorkspace=self.monitor) + +class BaseBeamFinder(ReductionStep): + """ + Base beam finder. Holds the position of the beam center + and the algorithm for calculates it using the beam's + displacement under gravity + """ + def __init__(self, beam_center_x=None, beam_center_y=None): + """ + Initial beam center is given in pixel coordinates + @param beam_center_x: pixel position of the beam in x + @param beam_center_y: pixel position of the beam in y + """ + super(BaseBeamFinder, self).__init__() + self._beam_center_x = beam_center_x + self._beam_center_y = beam_center_y + self._beam_radius = None + self._datafile = None + self._persistent = True + + def set_persistent(self, persistent): + self._persistent = persistent + return self + + def get_beam_center(self): + """ + Returns the beam center + """ + return [self._beam_center_x, self._beam_center_y] + + def execute(self, reducer, workspace=None): + return "Beam Center set at: %s %s" % (str(self._beam_center_x), str(self._beam_center_y)) + + class UserFile(ReductionStep): """ Reads an ISIS SANS mask file of the format described here mantidproject.org/SANS_User_File_Commands @@ -1672,7 +1918,7 @@ def execute(self, reducer, workspace=None): if not os.path.isfile(user_file): user_file = os.path.join(reducer.user_file_path, self.filename) if not os.path.isfile(user_file): - user_file = reducer._full_file_path(self.filename) + user_file = FileFinder.getFullPath(self.filename) if not os.path.isfile(user_file): raise RuntimeError, "Cannot read mask. File path '%s' does not exist or is not in the user path." % self.filename @@ -1745,9 +1991,9 @@ def read_line(self, line, reducer): y_pos = float(values[3])/1000.0 if (hab_str_pos > 0): print 'Front values = ',x_pos,y_pos - reducer.set_beam_finder(sans_reduction_steps.BaseBeamFinder(x_pos, y_pos),'front') + reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos),'front') else: - reducer.set_beam_finder(sans_reduction_steps.BaseBeamFinder(x_pos, y_pos)) + reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos)) elif upper_line.startswith('SET SCALES'): values = upper_line.split() @@ -2290,3 +2536,246 @@ def _padRunNumber(run_no, field_width): else: filebase = run_no[:digit_end].rjust(field_width, '0') return filebase + run_no[digit_end:], run_no[:digit_end] + + +class StripEndNans(ReductionStep): + # ISIS only + def __init__(self): + super(StripEndNans, self).__init__() + + def _isNan(self, val): + """ + Can replaced by isNaN in Python 2.6 + @param val: float to check + """ + if val != val: + return True + else: + return False + + def execute(self, reducer, workspace): + """ + Trips leading and trailing Nan values from workspace + @param reducer: unused + @param workspace: the workspace to convert + """ + result_ws = mtd[workspace] + if result_ws.getNumberHistograms() != 1: + #Strip zeros is only possible on 1D workspaces + return + + y_vals = result_ws.readY(0) + length = len(y_vals) + # Find the first non-zero value + start = 0 + for i in range(0, length): + if not self._isNan(y_vals[i]): + start = i + break + # Now find the last non-zero value + stop = 0 + length -= 1 + for j in range(length, 0,-1): + if not self._isNan(y_vals[j]): + stop = j + break + # Find the appropriate X values and call CropWorkspace + x_vals = result_ws.readX(0) + startX = x_vals[start] + # Make sure we're inside the bin that we want to crop + endX = 1.001*x_vals[stop + 1] + CropWorkspace(InputWorkspace=workspace, OutputWorkspace=workspace, XMin=startX, XMax=endX) + + +class GetSampleGeom(ReductionStep): + """ + Loads, stores, retrieves, etc. data about the geometry of the sample + On initialisation this class will return default geometry values (compatible with the Colette software) + There are functions to override these settings + On execute if there is geometry information in the workspace this will override any unset attributes + + ISIS only + ORNL only divides by thickness, in the absolute scaling step + + """ + # IDs for each shape as used by the Colette software + _shape_ids = {1 : 'cylinder-axis-up', + 2 : 'cuboid', + 3 : 'cylinder-axis-along'} + _default_shape = 'cylinder-axis-along' + + def __init__(self): + super(GetSampleGeom, self).__init__() + + # string specifies the sample's shape + self._shape = None + # sample's width + self._width = None + self._thickness = None + self._height = None + + self._use_wksp_shape = True + self._use_wksp_width = True + self._use_wksp_thickness = True + self._use_wksp_height = True + + def _get_default(self, attrib): + if attrib == 'shape': + return self._default_shape + elif attrib == 'width' or attrib == 'thickness' or attrib == 'height': + return 1.0 + + def set_shape(self, new_shape): + """ + Sets the sample's shape from a string or an ID. If the ID is not + in the list of allowed values the shape is set to the default but + shape strings not in the list are not checked + """ + try: + # deal with ID numbers as arguments + new_shape = self._shape_ids[int(new_shape)] + except ValueError: + # means that we weren't passed an ID number, the code below treats it as a shape name + pass + except KeyError: + _issueWarning("Warning: Invalid geometry type for sample: " + str(new_shape) + ". Setting default to " + self._default_shape) + new_shape = self._default_shape + + self._shape = new_shape + self._use_wksp_shape = False + + #check that the dimensions that we have make sense for our new shape + if self._width: + self.width = self._width + if self._thickness: + self.thickness = self._thickness + + def get_shape(self): + if self._shape is None: + return self._get_default('shape') + else: + return self._shape + + def set_width(self, width): + self._width = float(width) + self._use_wksp_width = False + # For a disk the height=width + if self._shape and self._shape.startswith('cylinder'): + self._height = self._width + self._use_wksp_height = False + + def get_width(self): + if self._width is None: + return self._get_default('width') + else: + return self._width + + def set_height(self, height): + self._height = float(height) + self._use_wksp_height = False + + # For a cylinder and sphere the height=width=radius + if (not self._shape is None) and (self._shape.startswith('cylinder')): + self._width = self._height + self._use_wksp_widtht = False + + def get_height(self): + if self._height is None: + return self._get_default('height') + else: + return self._height + + def set_thickness(self, thickness): + """ + Simply sets the variable _thickness to the value passed + """ + #as only cuboids use the thickness the warning below may be informative + #if (not self._shape is None) and (not self._shape == 'cuboid'): + # mantid.sendLogMessage('::SANS::Warning: Can\'t set thickness for shape "'+self._shape+'"') + self._thickness = float(thickness) + self._use_wksp_thickness = False + + def get_thickness(self): + if self._thickness is None: + return self._get_default('thickness') + else: + return self._thickness + + shape = property(get_shape, set_shape, None, None) + width = property(get_width, set_width, None, None) + height = property(get_height, set_height, None, None) + thickness = property(get_thickness, set_thickness, None, None) + + def execute(self, reducer, workspace): + """ + Reads the geometry information stored in the workspace + but doesn't replace values that have been previously set + """ + wksp = mtd[workspace] + if isinstance(wksp, WorkspaceGroup): + wksp = wksp[0] + sample_details = wksp.sample() + + if self._use_wksp_shape: + self.shape = sample_details.getGeometryFlag() + if self._use_wksp_thickness: + self.thickness = sample_details.getThickness() + if self._use_wksp_width: + self.width = sample_details.getWidth() + if self._use_wksp_height: + self.height = sample_details.getHeight() + + def __str__(self): + return '-- Sample Geometry --\n' + \ + ' Shape: ' + self.shape+'\n'+\ + ' Width: ' + str(self.width)+'\n'+\ + ' Height: ' + str(self.height)+'\n'+\ + ' Thickness: ' + str(self.thickness)+'\n' + +class SampleGeomCor(ReductionStep): + """ + Correct the neutron count rates for the size of the sample + + ISIS only + ORNL only divides by thickness, in the absolute scaling step + + """ + def __init__(self): + self.volume = 1.0 + + def calculate_volume(self, reducer): + geo = reducer.get_sample().geometry + assert( issubclass(geo.__class__, GetSampleGeom)) + + try: + if geo.shape == 'cylinder-axis-up': + # Volume = circle area * height + # Factor of four comes from radius = width/2 + volume = geo.height*math.pi + volume *= math.pow(geo.width,2)/4.0 + elif geo.shape == 'cuboid': + # Flat plate sample + volume = geo.width + volume *= geo.height*geo.thickness + elif geo.shape == 'cylinder-axis-along': + # Factor of four comes from radius = width/2 + # Disc - where height is not used + volume = geo.thickness*math.pi + volume *= math.pow(geo.width, 2)/4.0 + else: + raise NotImplemented('Shape "'+geo.shape+'" is not in the list of supported shapes') + except TypeError: + raise TypeError('Error calculating sample volume with width='+str(geo.width) + ' height='+str(geo.height) + 'and thickness='+str(geo.thickness)) + + return volume + + def execute(self, reducer, workspace): + """ + Divide the counts by the volume of the sample + """ + if not reducer.is_can(): + # it calculates the volume for the sample and may or not apply to the can as well. + self.volume = self.calculate_volume(reducer) + + ws = mtd[str(workspace)] + ws /= self.volume From ef046140177320ce304502c96c51b8952e3e87ec Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:15:26 +0000 Subject: [PATCH 008/118] re #9014. Bring Instrument to isis_instrument --- Code/Mantid/scripts/SANS/isis_instrument.py | 82 ++++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/scripts/SANS/isis_instrument.py b/Code/Mantid/scripts/SANS/isis_instrument.py index a41153a4adf2..66fb3711e9eb 100644 --- a/Code/Mantid/scripts/SANS/isis_instrument.py +++ b/Code/Mantid/scripts/SANS/isis_instrument.py @@ -1,13 +1,89 @@ -from reduction import instrument import math from mantid.simpleapi import * from mantid.api import WorkspaceGroup from mantid.kernel import Logger +import SANSUtility as su import re sanslog = Logger.get("SANS") import sys +class BaseInstrument(object): + def __init__(self, instr_filen=None): + """ + Reads the instrument definition xml file + @param instr_filen: the name of the instrument definition file to read + @raise IndexError: if any parameters (e.g. 'default-incident-monitor-spectrum') aren't in the xml definition + """ + if instr_filen is None: + instr_filen = self._NAME+'_Definition.xml' + + config = ConfigService.Instance() + self._definition_file = config["instrumentDefinition.directory"]+'/'+instr_filen + + self.definition = self.load_instrument() + + def load_instrument(self): + """ + Runs LoadInstrument get the parameters for the instrument + @return the instrument parameter data + """ + wrksp = '__'+self._NAME+'instrument_definition' + if not AnalysisDataService.doesExist(wrksp): + CreateWorkspace(OutputWorkspace=wrksp,DataX="1",DataY="1",DataE="1") + #read the information about the instrument that stored in its xml + LoadInstrument(Workspace=wrksp, InstrumentName=self._NAME) + + return AnalysisDataService.retrieve(wrksp).getInstrument() + + def get_default_beam_center(self): + """ + Returns the default beam center position, or the pixel location + of real-space coordinates (0,0). + """ + return [0, 0] + + def name(self): + """ + Return the name of the instrument + """ + return self._NAME + + def view(self, workspace_name = None): + """ + Opens Mantidplot's InstrumentView displaying the current instrument. This + empty instrument created contained in the named workspace (a default name + is generated if this the argument is left blank) unless the workspace already + exists and then it's contents are displayed + @param workspace_name: the name of the workspace to create and/or display + """ + if workspace_name is None: + workspace_name = self._NAME+'_instrument_view' + self.load_empty(workspace_name) + elif not AnalysisDataService.doesExist(workspace_name): + self.load_empty(workspace_name) + + import mantidplot + instrument_win = mantidplot.getInstrumentView(workspace_name) + instrument_win.show() + + return workspace_name + + def load_empty(self, workspace_name = None): + """ + Loads the instrument definition file into a workspace with the given name. + If no name is given a hidden workspace is used + @param workspace_name: the name of the workspace to create and/or display + @return the name of the workspace that was created + """ + if workspace_name is None: + workspace_name = '__'+self._NAME+'_empty' + + LoadEmptyInstrument(Filename=self._definition_file, OutputWorkspace=workspace_name) + + return workspace_name + + class DetectorBank: class _DectShape: """ @@ -328,14 +404,14 @@ def crop_to_detector(self, input_name, output_name=None): %(self.name(), input_name,self.get_first_spec_num(),self.last_spec_num) + str(sys.exc_info())) -class ISISInstrument(instrument.Instrument): +class ISISInstrument(BaseInstrument): def __init__(self, filename=None): """ Reads the instrument definition xml file @param filename: the name of the instrument definition file to read @raise IndexError: if any parameters (e.g. 'default-incident-monitor-spectrum') aren't in the xml definition """ - instrument.Instrument.__init__(self, instr_filen=filename) + super(ISISInstrument, self).__init__(instr_filen=filename) #the spectrum with this number is used to normalize the workspace data self._incid_monitor = int(self.definition.getNumberParameter( From c05d1abf4bda83d4be5295904e46668989a71253 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:16:45 +0000 Subject: [PATCH 009/118] re #9014: Addapt isis_reducer to the changes Do not use more things on reduction folder, but instead the SANS ones. --- Code/Mantid/scripts/SANS/isis_reducer.py | 74 +++++++++++++++--------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/Code/Mantid/scripts/SANS/isis_reducer.py b/Code/Mantid/scripts/SANS/isis_reducer.py index 850ae5f25e1c..b506a8eba65a 100644 --- a/Code/Mantid/scripts/SANS/isis_reducer.py +++ b/Code/Mantid/scripts/SANS/isis_reducer.py @@ -5,8 +5,7 @@ understand what's happening and how best to fit it in the Reducer design. """ -from reduction.instruments.sans.sans_reducer import SANSReducer -import reduction.instruments.sans.sans_reduction_steps as sans_reduction_steps +from reducer_singleton import Reducer import isis_reduction_steps from mantid.simpleapi import * from mantid.api import IEventWorkspace @@ -37,7 +36,7 @@ def __init__(self): #will contain a LoadSample() object that converts the run number into a file name and loads that file self.loader = None #geometry that comes from the run and can be overridden by user settings - self.geometry = sans_reduction_steps.GetSampleGeom() + self.geometry = isis_reduction_steps.GetSampleGeom() #record options for the set_run self.run_option = None self.reload_option = None @@ -91,7 +90,7 @@ def set_run(self, run, reload, period, reducer): if su.isEventWorkspace(name): su.fromEvent2Histogram(mtd[name]) -class ISISReducer(SANSReducer): +class ISISReducer(Reducer): """ ISIS Reducer @@ -103,7 +102,9 @@ class ISISReducer(SANSReducer): TODO: need documentation for all the data member TODO: need to see whether all those data members really belong here - """ + """ + ## Beam center finder ReductionStep object + _beam_finder = None _front_beam_finder = None QXY2 = None @@ -152,7 +153,7 @@ def _init_steps(self): #except self.prep_normalize all the steps below are used by the reducer self.crop_detector = isis_reduction_steps.CropDetBank() - self.mask =self._mask= isis_reduction_steps.Mask_ISIS() + self.mask = isis_reduction_steps.Mask_ISIS() self.to_wavelen = isis_reduction_steps.UnitsConvert('Wavelength') self.norm_mon = isis_reduction_steps.NormalizeToMonitor() self.transmission_calculator =\ @@ -169,9 +170,9 @@ def _init_steps(self): self.to_Q = isis_reduction_steps.ConvertToQISIS( self.prep_normalize) self._background_subtracter = isis_reduction_steps.CanSubtraction() - self.geometry_correcter = sans_reduction_steps.SampleGeomCor() + self.geometry_correcter = isis_reduction_steps.SampleGeomCor() # self._zero_error_flags=isis_reduction_steps.ReplaceErrors() - self._rem_nans = sans_reduction_steps.StripEndNans() + self._rem_nans = isis_reduction_steps.StripEndNans() self.set_Q_output_type(self.to_Q.output_type) # keep information about event slicing @@ -188,8 +189,7 @@ def _clean_loaded_data(self): def __init__(self): - SANSReducer.__init__(self) - self._dark_current_subtracter_class = None + super(ISISReducer, self).__init__() self.output_wksp = None self.full_trans_wav = False self._monitor_set = False @@ -205,9 +205,6 @@ def __init__(self): #process the background (can) run instead of the sample self._process_can = False - # Python 2.4 has a problem deep copying the _resolution_calculator in - # the base class. ISIS don't need it so kill it off here - self._resolution_calculator = None #option to indicate if wide_angle_correction will be applied. self.wide_angle_correction = False # Due to the way that ISISReducer is used to the reduction of the Can @@ -220,6 +217,17 @@ def __init__(self): self.__transmission_can = "" + def set_instrument(self, configuration): + """ + Sets the instrument and put in the default beam center (usually the + center of the detector) + @param configuration: instrument object + """ + super(ISISReducer, self).set_instrument(configuration) + center = self.instrument.get_default_beam_center() + self._beam_finder = isis_reduction_steps.BaseBeamFinder(center[0], center[1]) + + def set_sample(self, run, reload, period): """ Assigns and load the run that this reduction chain will analysis @@ -402,7 +410,21 @@ def set_Q_output_type(self, out_type): self.to_Q.set_output_type(out_type) def pre_process(self): - super(ISISReducer, self).pre_process() + """ + Reduction steps that are meant to be executed only once per set + of data files. After this is executed, all files will go through + the list of reduction steps. + """ + if self.instrument is None: + raise RuntimeError, "ISISReducer: trying to run a reduction with no instrument specified" + + if self._beam_finder is not None: + result = self._beam_finder.execute(self) + self.log_text += "%s\n" % str(result) + + # Create the list of reduction steps + self._to_steps() + self._out_name.execute(self) global current_settings current_settings = copy.deepcopy(self) @@ -509,7 +531,7 @@ def ViewCurrentMask(self): In MantidPlot this opens InstrumentView to display the masked detectors in the bank in a different colour """ - self._mask.view(self.instrument) + self.mask.view(self.instrument) def reference(self): return self @@ -528,7 +550,7 @@ def set_beam_finder(self, finder, det_bank='rear'): @param finder: BaseBeamFinder object @param det_bank: two valid options: 'rear', 'front' """ - if issubclass(finder.__class__, sans_reduction_steps.BaseBeamFinder) or finder is None: + if issubclass(finder.__class__, isis_reduction_steps.BaseBeamFinder) or finder is None: if det_bank == 'front': self._front_beam_finder = finder else: @@ -585,15 +607,15 @@ def setSlicesLimits(self, str_def): self._slices_def = su.sliceParser(str_def) self._slice_index = 0 -def deleteWorkspaces(workspaces): - """ + def deleteWorkspaces(self, workspaces): + """ Deletes a list of workspaces if they exist but ignores any errors - """ - for wk in workspaces: - try: - if wk and wk in mtd: - DeleteWorkspace(Workspace=wk) - except: - #if the workspace can't be deleted this function does nothing - pass + """ + for wk in workspaces: + try: + if wk and wk in mtd: + DeleteWorkspace(Workspace=wk) + except: + #if the workspace can't be deleted this function does nothing + pass From bcfde5653e835fd97b54efbffcb5204ea19e09d5 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:17:14 +0000 Subject: [PATCH 010/118] re #9014 Update centre_finder to not user old sans_reduction_steps --- Code/Mantid/scripts/SANS/centre_finder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/scripts/SANS/centre_finder.py b/Code/Mantid/scripts/SANS/centre_finder.py index e9a3f61ed20e..cb3dc799ccf0 100644 --- a/Code/Mantid/scripts/SANS/centre_finder.py +++ b/Code/Mantid/scripts/SANS/centre_finder.py @@ -1,5 +1,5 @@ import isis_reducer -import reduction.instruments.sans.sans_reduction_steps as sans_reduction_steps +from isis_reduction_steps import StripEndNans from mantid.simpleapi import * from mantid.kernel import Logger import SANSUtility @@ -67,7 +67,7 @@ def SeekCentre(self, setup, trial): for out_wksp in self.QUADS: in_wksp = out_wksp+'_tmp' ReplaceSpecialValues(InputWorkspace=in_wksp,OutputWorkspace=in_wksp,NaNValue=0,InfinityValue=0) - rem_nans = sans_reduction_steps.StripEndNans() + rem_nans = StripEndNans() rem_nans.execute(setup, in_wksp) RenameWorkspace(InputWorkspace=in_wksp,OutputWorkspace= out_wksp) From 0806e1df85246cba8817924b24f5e1c9998088eb Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:19:13 +0000 Subject: [PATCH 011/118] re #9014. Adapt ISISCommandInterface to use only SANS folder --- Code/Mantid/scripts/SANS/ISISCommandInterface.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Code/Mantid/scripts/SANS/ISISCommandInterface.py b/Code/Mantid/scripts/SANS/ISISCommandInterface.py index 514e9106f7e3..09f3c7904493 100644 --- a/Code/Mantid/scripts/SANS/ISISCommandInterface.py +++ b/Code/Mantid/scripts/SANS/ISISCommandInterface.py @@ -3,9 +3,9 @@ be run """ import isis_instrument -from reduction.command_interface import ReductionSingleton -import reduction.instruments.sans.sans_reduction_steps as sans_reduction_steps -sanslog = sans_reduction_steps.sanslog +from reducer_singleton import ReductionSingleton +from mantid.kernel import Logger +sanslog = Logger.get("SANS") import isis_reduction_steps import isis_reducer @@ -326,7 +326,7 @@ def SetCentre(xcoord, ycoord, bank = 'rear'): """ _printMessage('SetCentre(' + str(xcoord) + ', ' + str(ycoord) + ')') - ReductionSingleton().set_beam_finder(sans_reduction_steps.BaseBeamFinder( + ReductionSingleton().set_beam_finder(isis_reduction_steps.BaseBeamFinder( float(xcoord)/1000.0, float(ycoord)/1000.0), bank) def GetMismatchedDetList(): @@ -1095,7 +1095,7 @@ def FindBeamCentre(rlow, rupp, MaxIter = 10, xstart = None, ystart = None, toler if xstart or ystart: ReductionSingleton().set_beam_finder( - sans_reduction_steps.BaseBeamFinder( + isis_reduction_steps.BaseBeamFinder( float(xstart), float(ystart)),det_bank) beamcoords = ReductionSingleton().get_beam_center() @@ -1127,7 +1127,7 @@ def FindBeamCentre(rlow, rupp, MaxIter = 10, xstart = None, ystart = None, toler it = i centre_reduction.set_beam_finder( - sans_reduction_steps.BaseBeamFinder(XNEW, YNEW), det_bank) + isis_reduction_steps.BaseBeamFinder(XNEW, YNEW), det_bank) resX, resY = centre.SeekCentre(centre_reduction, [XNEW, YNEW]) centre_reduction = copy.deepcopy(ReductionSingleton().reference()) @@ -1167,7 +1167,7 @@ def FindBeamCentre(rlow, rupp, MaxIter = 10, xstart = None, ystart = None, toler YNEW -= YSTEP ReductionSingleton().set_beam_finder( - sans_reduction_steps.BaseBeamFinder(XNEW, YNEW), det_bank) + isis_reduction_steps.BaseBeamFinder(XNEW, YNEW), det_bank) centre.logger.notice("Centre coordinates updated: [" + str(XNEW)+ ", "+ str(YNEW) + ']') return XNEW, YNEW From 1d0f78a77298a9cd6cfd25ba564006e3090fa818 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:26:34 +0000 Subject: [PATCH 012/118] re #9014 Improve usage of mantidplot when not in GUI mode While testing the changes, I've seen that we were silently ignoring exception when trying to use mantidplot in script mode. It is better to check if it is available and use only when it is. --- .../scripts/SANS/ISISCommandInterface.py | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/Code/Mantid/scripts/SANS/ISISCommandInterface.py b/Code/Mantid/scripts/SANS/ISISCommandInterface.py index 09f3c7904493..212860fbdb26 100644 --- a/Code/Mantid/scripts/SANS/ISISCommandInterface.py +++ b/Code/Mantid/scripts/SANS/ISISCommandInterface.py @@ -21,6 +21,7 @@ try: import mantidplot except: + mantidplot = None #this should happen when this is called from outside Mantidplot and only then, the result is that attempting to plot will raise an exception pass @@ -741,7 +742,7 @@ def CompWavRanges(wavelens, plot=True, combineDet=None, resetSetup=True): if resetSetup: _refresh_singleton() - if plot: + if plot and mantidplot: mantidplot.plotSpectrum(calculated, 0) #return just the workspace name of the full range @@ -774,7 +775,7 @@ def PhiRanges(phis, plot=True): finally: _refresh_singleton() - if plot: + if plot and mantidplot: mantidplot.plotSpectrum(calculated, 0) #return just the workspace name of the full range @@ -949,6 +950,10 @@ def PlotResult(workspace, canvas=None): @param canvas: optional handle to an existing graph to write the plot to @return: a handle to the graph that was written to """ + if not mantidplot: + issueWarning('Plot functions are not available, is this being run from outside Mantidplot?') + return + #ensure that we are dealing with a workspace handle rather than its name workspace = mtd[str(workspace)] if isinstance(workspace, WorkspaceGroup): @@ -956,14 +961,10 @@ def PlotResult(workspace, canvas=None): else: numSpecs = workspace.getNumberHistograms() - try: - if numSpecs == 1: - graph = mantidplot.plotSpectrum(workspace,0) - else: - graph = mantidplot.importMatrixWorkspace(workspace.getName()).plotGraph2D() - - except NameError: - issueWarning('Plot functions are not available, is this being run from outside Mantidplot?') + if numSpecs == 1: + graph = mantidplot.plotSpectrum(workspace,0) + else: + graph = mantidplot.importMatrixWorkspace(workspace.getName()).plotGraph2D() if not canvas is None: #we were given a handle to an existing graph, use it @@ -1135,15 +1136,16 @@ def FindBeamCentre(rlow, rupp, MaxIter = 10, xstart = None, ystart = None, toler centre.logger.notice(centre.status_str(it, resX, resY)) - try : - if not graph_handle: - #once we have a plot it will be updated automatically when the workspaces are updated - graph_handle = mantidplot.plotSpectrum(centre.QUADS, 0) - graph_handle.activeLayer().setTitle( + if mantidplot: + try : + if not graph_handle: + #once we have a plot it will be updated automatically when the workspaces are updated + graph_handle = mantidplot.plotSpectrum(centre.QUADS, 0) + graph_handle.activeLayer().setTitle( centre.status_str(it, resX, resY)) - except : - #if plotting is not available it probably means we are running outside a GUI, in which case do everything but don't plot - pass + except : + #if plotting is not available it probably means we are running outside a GUI, in which case do everything but don't plot + pass #have we stepped across the y-axis that goes through the beam center? if resX > resX_old: From f2290b50c26e7167b1055907fec2c79df0287f07 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:29:49 +0000 Subject: [PATCH 013/118] re #9014. Improve the solution for long log The changes here were introduced in #8949, but while testing the changes through the systemtests I reckognise that some times it may return a single value. Hence, here it tests first if there are more than one value before selecting the last one. --- Code/Mantid/scripts/SANS/isis_instrument.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/scripts/SANS/isis_instrument.py b/Code/Mantid/scripts/SANS/isis_instrument.py index 66fb3711e9eb..1f2eb25b61ad 100644 --- a/Code/Mantid/scripts/SANS/isis_instrument.py +++ b/Code/Mantid/scripts/SANS/isis_instrument.py @@ -839,7 +839,9 @@ def getDetValues(self, ws_name): for name in ('Front_Det_Z', 'Front_Det_X', 'Front_Det_Rot', 'Rear_Det_Z','Rear_Det_X'): try: - var = run_info.get(name).value[-1] + var = run_info.get(name).value + if hasattr(var, '__iter__'): + var = var[-1] values[ind] = float(var) except: pass # ignore, because we do have a default value From 77625780a4abd71cfcc6285d8fbc9e743c7f8a2b Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 20 Feb 2014 17:31:54 +0000 Subject: [PATCH 014/118] re #9014. Ensure assumption of receiving workspace reference While checking this ticket I found that some system tests were passing string to this method and were 'silently' being ignored. This, fixes it. --- Code/Mantid/scripts/SANS/isis_instrument.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/scripts/SANS/isis_instrument.py b/Code/Mantid/scripts/SANS/isis_instrument.py index 1f2eb25b61ad..22e0b04ef3f0 100644 --- a/Code/Mantid/scripts/SANS/isis_instrument.py +++ b/Code/Mantid/scripts/SANS/isis_instrument.py @@ -942,6 +942,7 @@ def get_detector_log(self, wksp): @return the values that were read as a dictionary """ self._marked_dets = [] + wksp = su.getWorkspaceReference(wksp) #assume complete log information is stored in the first entry, it isn't stored in the group workspace itself if isinstance(wksp, WorkspaceGroup): wksp = wksp[0] From fbd93ed32565c25da73538172157bd2af29016dc Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Fri, 21 Feb 2014 17:29:13 -0500 Subject: [PATCH 015/118] Re #9073. Fix the ExperimentInfo::run docstring. It had obviously been copy-pasted and not fixed up to refer to the right thing. --- .../PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp index 5e72e2d1979b..22316480d3dc 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp @@ -33,7 +33,7 @@ void export_ExperimentInfo() args("self"), "Return a modifiable Sample object.") .def("run", &ExperimentInfo::run, return_value_policy(), - args("self"), "Return the sample object. This cannot be modified, use mutableSample to modify.") + args("self"), "Return the Run object. This cannot be modified, use mutableRun to modify.") .def("mutableRun", &ExperimentInfo::mutableRun, return_value_policy(), args("self"), "Return a modifiable Run object.") From 53d78a3bdd5e742788c07b96e0e96ee4ced75feb Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 25 Feb 2014 15:14:04 +0000 Subject: [PATCH 016/118] Remove create in catalogFactory. Refs #9084. --- .../API/inc/MantidAPI/CatalogFactory.h | 4 ---- .../Framework/API/src/CatalogFactory.cpp | 21 ------------------- 2 files changed, 25 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h index f4678145133d..501d65ad34cd 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h @@ -72,10 +72,6 @@ class ICatalog; */ class MANTID_API_DLL CatalogFactoryImpl : public Kernel::DynamicFactory { -public: - /// create an instance of the catalog specified by the calssName - virtual boost::shared_ptr create(const std::string& className) const; - private: friend struct Kernel::CreateUsingNew; diff --git a/Code/Mantid/Framework/API/src/CatalogFactory.cpp b/Code/Mantid/Framework/API/src/CatalogFactory.cpp index f61c504cf5f5..de7cf002fada 100644 --- a/Code/Mantid/Framework/API/src/CatalogFactory.cpp +++ b/Code/Mantid/Framework/API/src/CatalogFactory.cpp @@ -17,26 +17,5 @@ CatalogFactoryImpl::~CatalogFactoryImpl() { } -/** Returns an instance of the class with the given name. Overrides the base class method. - * If an instance already exists, a pointer to it is returned, otherwise - * a new instance is created by the DynamicFactory::create method. - * @param className :: The name of the class to be created - * @return A shared pointer to the instance of the requested unit - */ -boost::shared_ptr CatalogFactoryImpl::create(const std::string& className) const -{ - std::map< std::string, boost::shared_ptr >::const_iterator it = m_createdCatalogs.find(className); - if ( it != m_createdCatalogs.end() ) - { - // If an instance has previously been created, just return a pointer to it - return it->second; - } - else - { - // Otherwise create & return a new instance and store the pointer in the internal map for next time - return m_createdCatalogs[className] = Kernel::DynamicFactory::create(className); - } -} - } // namespace Kernel } // namespace Mantid From 70a968b79db70ed5e7f7e66b6b9ebadfe026aba4 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 25 Feb 2014 15:20:14 +0000 Subject: [PATCH 017/118] Tidied up catalogFactory class and header. Refs #9084. --- .../API/inc/MantidAPI/CatalogFactory.h | 142 +++++++++--------- .../Framework/API/src/CatalogFactory.cpp | 23 +-- 2 files changed, 75 insertions(+), 90 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h index 501d65ad34cd..9c3393449ac4 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h @@ -25,81 +25,73 @@ namespace Mantid { -//---------------------------------------------------------------------- -// Forward declaration -//---------------------------------------------------------------------- -namespace Kernel -{ - class Logger; -} -namespace API -{ - -//---------------------------------------------------------------------- -// Forward declaration -//---------------------------------------------------------------------- - -class ICatalog; - -/** Creates instances of concrete Catalog. - The factory is a singleton that hands out shared pointers to the base Catalog class. - It overrides the base class DynamicFactory::create method so that only a single - instance of a given Catalog is ever created, and a pointer to that same instance - is passed out each time the Catalog is requested. - - @author Sofia Antony - @date 01/10/2010 - - Copyright © 2008 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: -*/ -class MANTID_API_DLL CatalogFactoryImpl : public Kernel::DynamicFactory -{ -private: - friend struct Kernel::CreateUsingNew; - - /// Private Constructor for singleton class - CatalogFactoryImpl(); - /// Private copy constructor - CatalogFactoryImpl(const CatalogFactoryImpl&); - /// Private assignment operator - CatalogFactoryImpl& operator = (const CatalogFactoryImpl&); - ///Private Destructor - virtual ~CatalogFactoryImpl(); - - /// Stores pointers to already created Catalog instances, with their name as the key - mutable std::map< std::string, boost::shared_ptr > m_createdCatalogs; - - /// Reference to the logger class - Kernel::Logger& m_log; -}; - -///Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) . -#ifdef _WIN32 -// this breaks new namespace declaraion rules; need to find a better fix - template class MANTID_API_DLL Mantid::Kernel::SingletonHolder; -#endif /* _WIN32 */ -/// The specialisation of the SingletonHolder class that holds the CatalogFactory -typedef Mantid::Kernel::SingletonHolder CatalogFactory; - -} // namespace API + //---------------------------------------------------------------------- + // Forward declaration + //---------------------------------------------------------------------- + namespace Kernel + { + class Logger; + } + + namespace API + { + //---------------------------------------------------------------------- + // Forward declaration + //---------------------------------------------------------------------- + class ICatalog; + + /** + The factory is a singleton that hands out shared pointers to the base Catalog class. + + @author Sofia Antony, ISIS Rutherford Appleton Laboratory + @date 01/10/2010 + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: . + Code Documentation is available at: + */ + class MANTID_API_DLL CatalogFactoryImpl : public Kernel::DynamicFactory + { + private: + friend struct Kernel::CreateUsingNew; + /// Private Constructor for singleton class + CatalogFactoryImpl(); + /// Private copy constructor + CatalogFactoryImpl(const CatalogFactoryImpl&); + /// Private assignment operator + CatalogFactoryImpl& operator = (const CatalogFactoryImpl&); + /// Private Destructor + virtual ~CatalogFactoryImpl(); + /// Stores pointers to already created Catalog instances, with their name as the key + mutable std::map< std::string, boost::shared_ptr > m_createdCatalogs; + /// Reference to the logger class + Kernel::Logger& m_log; + }; + + ///Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) . + #ifdef _WIN32 + // this breaks new namespace declaraion rules; need to find a better fix + template class MANTID_API_DLL Mantid::Kernel::SingletonHolder; + #endif /* _WIN32 */ + /// The specialisation of the SingletonHolder class that holds the CatalogFactory + typedef Mantid::Kernel::SingletonHolder CatalogFactory; + + } // namespace API } // namespace Mantid #endif /*MANTID_API_CatalogFACTORYIMPL_H_*/ diff --git a/Code/Mantid/Framework/API/src/CatalogFactory.cpp b/Code/Mantid/Framework/API/src/CatalogFactory.cpp index de7cf002fada..5259ee6edeba 100644 --- a/Code/Mantid/Framework/API/src/CatalogFactory.cpp +++ b/Code/Mantid/Framework/API/src/CatalogFactory.cpp @@ -3,19 +3,12 @@ namespace Mantid { -namespace API -{ - -/// Constructor -CatalogFactoryImpl::CatalogFactoryImpl() : - Kernel::DynamicFactory(), m_createdCatalogs(), m_log(Kernel::Logger::get("CatalogFactory")) -{ + namespace API + { + /// Constructor + CatalogFactoryImpl::CatalogFactoryImpl() : + Kernel::DynamicFactory(), m_createdCatalogs(), m_log(Kernel::Logger::get("CatalogFactory")) {} + /// Destructor + CatalogFactoryImpl::~CatalogFactoryImpl(){} + } } - - /// Destructor -CatalogFactoryImpl::~CatalogFactoryImpl() -{ -} - -} // namespace Kernel -} // namespace Mantid From e5412a801c360af922713c06fb2fe129dd0087b3 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 14:46:31 +0000 Subject: [PATCH 018/118] Added initial structure of catalogManager. Refs #9084. --- .../ICat/inc/MantidICat/CatalogManager.h | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h new file mode 100644 index 000000000000..93d870c249b7 --- /dev/null +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h @@ -0,0 +1,71 @@ +#ifndef MANTID_ICAT_CATALOGMANAGERIMPL_H_ +#define MANTID_ICAT_CATALOGMANAGERIMPL_H_ + +#include "MantidKernel/SingletonHolder.h" +#include "MantidICat/CompositeCatalog.h" + +namespace Mantid +{ + namespace ICat + { + /** + This class is a singleton and is responsible for creating, destroying, and managing catalogs. + + @author Jay Rainey, ISIS Rutherford Appleton Laboratory + @date 26/02/2014 + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: . + Code Documentation is available at: + */ + class DLLExport CatalogManagerImpl + { + public: + /// Create a new catalog, and add it to the list of active catalogs. + API::ICatalog_sptr create(const std::string facilityName); + /// Get a specific catalog using the sessionID. + API::ICatalog_sptr getCatalog(const std::string sessionID); + /// Get a list of all active catalogs. + boost::shared_ptr getCatalogs(); + /// Destroy and remove a specific catalog from the active catalogs list. + void destroyCatalog(const std::string sessionID); + /// Destroy all active catalogs. + void destroyCatalogs(); + + private: + /// These methods are required to create a singleton. + friend struct Kernel::CreateUsingNew; + CatalogManagerImpl(); + CatalogManagerImpl(const CatalogManagerImpl&); + CatalogManagerImpl& operator = (const CatalogManagerImpl&); + virtual ~CatalogManagerImpl(); + + // Holds a list of active catalogs and uses their sessionId as unique identifier. + std::map m_activeCatalogs; + // Used to return the compositeCatalog that holds the created catalogs. + boost::shared_ptr m_compositeCatalog; + }; + + #ifdef _WIN32 + template class DLLExport Kernel::SingletonHolder; + #endif + typedef Kernel::SingletonHolder CatalogManager; + + } +} +#endif /* MANTID_ICAT_CATALOGMANAGERIMPL_H_ */ From b8c9d9b28a657f21a782fc0d458d3635f58ced92 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 15:05:00 +0000 Subject: [PATCH 019/118] Added catalogManager implementation. Refs #9084. - Missing destroyCatalog and destroyCatalogs as changes to compositeCatalog need to be made to expose the member variable. - create will not currently work as there is no way to obtain the sessionID of multiple catalogs. --- Code/Mantid/Framework/ICat/CMakeLists.txt | 2 + .../Framework/ICat/src/CatalogManager.cpp | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 Code/Mantid/Framework/ICat/src/CatalogManager.cpp diff --git a/Code/Mantid/Framework/ICat/CMakeLists.txt b/Code/Mantid/Framework/ICat/CMakeLists.txt index 7bdfc8ed9f95..6e745a9672c5 100644 --- a/Code/Mantid/Framework/ICat/CMakeLists.txt +++ b/Code/Mantid/Framework/ICat/CMakeLists.txt @@ -12,6 +12,7 @@ set ( SRC_FILES src/CatalogSearch.cpp src/CatalogSearchParam.cpp src/CompositeCatalog.cpp + src/CatalogManager.cpp src/GSoap.cpp src/ICat3/ICat3GSoapGenerated.cpp src/ICat3/ICat3ErrorHandling.cpp @@ -39,6 +40,7 @@ set ( INC_FILES inc/MantidICat/ICatExport.h inc/MantidICat/Session.h inc/MantidICat/CompositeCatalog.h + inc/MantidICat/CatalogManager.h inc/MantidICat/GSoap/soapserializersH.h inc/MantidICat/GSoap/soapserializersStub.h inc/MantidICat/GSoap/stdsoap2.h diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp new file mode 100644 index 000000000000..1c78ce5b6aa8 --- /dev/null +++ b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp @@ -0,0 +1,64 @@ +#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogFactory.h" + +namespace Mantid +{ + namespace ICat + { + CatalogManagerImpl::CatalogManagerImpl() : m_activeCatalogs(), m_compositeCatalog(new CompositeCatalog()) {} + + CatalogManagerImpl::~CatalogManagerImpl(){} + + /** + * Creates a new catalog and adds it to the compositeCatalog and activeCatalog list. + * @param facilityName :: The name of the facility to create a catalog for. + * @return A catalog for the facility specified. + */ + API::ICatalog_sptr CatalogManagerImpl::create(const std::string facilityName) + { + auto catalog = API::CatalogFactory::Instance().create(facilityName); + m_compositeCatalog->add(catalog); + m_activeCatalogs.insert(std::make_pair("",catalog)); + return catalog; + } + + /** + * Obtain a specific catalog using the sessionID. + * @param sessionID :: The session to search for in the active catalogs list. + * @return A specific catalog using the sessionID. + */ + API::ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string sessionID) + { + auto pos = m_activeCatalogs.find(sessionID); + // If the key element exists in the map we want the related catalog. + if (pos != m_activeCatalogs.end()) return pos->second; + } + + /** + * Obtain a list of all active catalogs. + * @return A composite catalog object as it holds and performs operations on all catalogs. + */ + boost::shared_ptr CatalogManagerImpl::getCatalogs() + { + return m_compositeCatalog; + } + + /** + * Destroy and remove a specific catalog from the active catalogs list and the composite catalog. + * @param sessionID :: The session to search for in the active catalogs list. + */ + void CatalogManagerImpl::destroyCatalog(const std::string sessionID) + { + + } + + /** + * Destroy all active catalogs. + */ + void CatalogManagerImpl::destroyCatalogs() + { + + } + + } +} From 45ab87f288ce1f38ec3b992d9f580aa5597f253c Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 15:13:52 +0000 Subject: [PATCH 020/118] Add implementation to remaining catalog manager methods. Refs #9084. - Added new methods to expose the compositeCatalog container to CatalogManager. --- .../ICat/inc/MantidICat/CompositeCatalog.h | 9 +++++++-- .../Framework/ICat/src/CatalogManager.cpp | 11 ++++++++++- .../Framework/ICat/src/CompositeCatalog.cpp | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h index c4512c147617..f1fc9688b34d 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h @@ -39,6 +39,11 @@ namespace Mantid CompositeCatalog(); /// Adds a catalog to the list of catalogs (m_catalogs) void add(const API::ICatalog_sptr catalog); + /// Remove a specific catalog from the list of catalogs. + void removeCatalogFromComposite(API::ICatalog_sptr& catalog); + /// Clear the list of catalogs. + void clearCompositeCatalog(); + /// Log the user into the catalog system. virtual void login(const std::string& username,const std::string& password,const std::string& endpoint); /// Log the user out of the catalog system. @@ -51,9 +56,9 @@ namespace Mantid /// Show the logged in user's investigations search results. virtual void myData(API::ITableWorkspace_sptr& outputws); /// Get datasets. - virtual void getDataSets(const std::string&investigationId,API::ITableWorkspace_sptr& outputws); + virtual void getDataSets(const std::string& investigationId,API::ITableWorkspace_sptr& outputws); /// Get datafiles - virtual void getDataFiles(const std::string&investigationId,API::ITableWorkspace_sptr& outputws); + virtual void getDataFiles(const std::string& investigationId,API::ITableWorkspace_sptr& outputws); /// Get instruments list virtual void listInstruments(std::vector& instruments); /// Get investigationtypes list diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp index 1c78ce5b6aa8..73177a4aa1b7 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp @@ -49,7 +49,14 @@ namespace Mantid */ void CatalogManagerImpl::destroyCatalog(const std::string sessionID) { + auto pos = m_activeCatalogs.find(sessionID); + if (pos != m_activeCatalogs.end()) + { + pos->second->logout(); + m_compositeCatalog->removeCatalogFromComposite((pos->second)); + m_activeCatalogs.erase(pos); + } } /** @@ -57,7 +64,9 @@ namespace Mantid */ void CatalogManagerImpl::destroyCatalogs() { - + m_compositeCatalog->logout(); + m_compositeCatalog->clearCompositeCatalog(); + m_activeCatalogs.clear(); } } diff --git a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp b/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp index 8886b3420090..7cbc92fffc3f 100644 --- a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp +++ b/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp @@ -15,6 +15,23 @@ namespace Mantid m_catalogs.push_back(catalog); } + /** + * Remove a specific catalog from the catalog container. + * @param catalog :: The catalog to remove from the catlaog container. + */ + void CompositeCatalog::removeCatalogFromComposite(API::ICatalog_sptr& catalog) + { + std::remove(m_catalogs.begin(),m_catalogs.end(),catalog); + } + + /** + * Clear the catalog container. + */ + void CompositeCatalog::clearCompositeCatalog() + { + m_catalogs.clear(); + } + /** * Authenticate the user against all catalogues in the container. * @param username :: The login name of the user. From 02a7356a0cbee542edb89b1c4544df6f06c261ec Mon Sep 17 00:00:00 2001 From: Karl Palmen Date: Wed, 26 Feb 2014 16:14:44 +0000 Subject: [PATCH 021/118] Add XML version of flowchart for loadMuon re #9047 Signed-off-by: Karl Palmen --- Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml | 1 + 1 file changed, 1 insertion(+) create mode 100644 Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml diff --git a/Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml b/Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml new file mode 100644 index 000000000000..6964a28667c2 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml @@ -0,0 +1 @@ +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 \ No newline at end of file From 6e2d076af2cc28196b6bd7b6b6dccbe6f47c61fd Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 17:04:40 +0000 Subject: [PATCH 022/118] Remove cpp warning. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp index 73177a4aa1b7..515793b94885 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp @@ -32,6 +32,7 @@ namespace Mantid auto pos = m_activeCatalogs.find(sessionID); // If the key element exists in the map we want the related catalog. if (pos != m_activeCatalogs.end()) return pos->second; + else throw std::runtime_error("The session ID you have provided is invalid"); } /** From 349c1ee028fa8171cac43e3ba8b03181e9964314 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 17:32:24 +0000 Subject: [PATCH 023/118] Update algorithms to use catalogmanager. Refs #9084. - `CatalogDownloadDataFiles` and `CatalogPublish` are edge-cases in that they need to call `getCatalog`. --- .../Framework/ICat/src/CatalogGetDataFiles.cpp | 3 ++- .../Framework/ICat/src/CatalogGetDataSets.cpp | 3 ++- .../Framework/ICat/src/CatalogListInstruments.cpp | 7 ++++--- .../ICat/src/CatalogListInvestigationTypes.cpp | 12 ++++++------ Code/Mantid/Framework/ICat/src/CatalogLogin.cpp | 13 ++++++------- Code/Mantid/Framework/ICat/src/CatalogLogout.cpp | 4 +++- Code/Mantid/Framework/ICat/src/CatalogManager.cpp | 13 ++++++++----- .../Framework/ICat/src/CatalogMyDataSearch.cpp | 4 ++-- Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 9 +++++---- 9 files changed, 38 insertions(+), 30 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index c7c3e31e6c85..5cbb983407fd 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -5,6 +5,7 @@ This algorithm retrieves the files associated to selected investigation from the *WIKI*/ #include "MantidICat/CatalogGetDataFiles.h" +#include "MantidICat/CatalogManager.h" #include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidAPI/WorkspaceProperty.h" @@ -35,7 +36,7 @@ namespace Mantid void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogAlgorithmHelper().createCatalog()->getDataFiles(getProperty("InvestigationId"),workspace); + CatalogManager::Instance().getCatalogs()->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 2a2bba6d67a8..25103866ea81 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -4,6 +4,7 @@ from the information catalog and saves the search results to mantid workspace. *WIKI*/ #include "MantidICat/CatalogGetDataSets.h" +#include "MantidICat/CatalogManager.h" #include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidAPI/WorkspaceProperty.h" @@ -34,7 +35,7 @@ namespace Mantid void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogAlgorithmHelper().createCatalog()->getDataSets(getProperty("InvestigationId"),workspace); + CatalogManager::Instance().getCatalogs()->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 622a05510408..8a628b86c613 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -6,6 +6,7 @@ This algorithm retrieves the instrument names from a catalog and stores them in #include "MantidICat/CatalogListInstruments.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" namespace Mantid @@ -34,9 +35,9 @@ namespace Mantid /// exec method void CatalogListInstruments::exec() { - std::vector intruments; - CatalogAlgorithmHelper().createCatalog()->listInstruments(intruments); - setProperty("InstrumentList",intruments); + std::vector instruments; + CatalogManager::Instance().getCatalogs()->listInstruments(instruments); + setProperty("InstrumentList",instruments); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index fe8fc4c5373f..6d887984905b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -6,6 +6,7 @@ This algorithm is responsible for obtaining a list of investigation types from t #include "MantidICat/CatalogListInvestigationTypes.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" namespace Mantid @@ -25,17 +26,16 @@ namespace Mantid void CatalogListInvestigationTypes::init() { declareProperty( new Kernel::ArrayProperty("InvestigationTypes",std::vector(), - boost::make_shared(), - Kernel::Direction::Output), - "List of investigation types obtained from Catalog"); + boost::make_shared(), Kernel::Direction::Output), + "List of investigation types obtained from Catalog"); } /// exec method void CatalogListInvestigationTypes::exec() { - std::vector investTypes; - CatalogAlgorithmHelper().createCatalog()->listInvestigationTypes(investTypes); - setProperty("InvestigationTypes",investTypes); + std::vector investigationTypes; + CatalogManager::Instance().getCatalogs()->listInvestigationTypes(investigationTypes); + setProperty("InvestigationTypes",investigationTypes); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp index 5e1fab8a4e87..b8d50d7579ce 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp @@ -6,6 +6,7 @@ This algorithm connects the logged in user to the information catalog. #include "MantidICat/CatalogLogin.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/MaskedProperty.h" #include "MantidKernel/ListValidator.h" @@ -38,14 +39,12 @@ namespace Mantid /// execute the algorithm void CatalogLogin::exec() { - // Obtain the soapEndPoint based on the name of the facility the user has selected. - std::string soapEndPoint = Kernel::ConfigService::Instance().getFacility(getProperty("FacilityName")).catalogInfo().soapEndPoint(); - if (soapEndPoint.empty()) throw std::runtime_error("There is no soap end-point for the facility you have selected."); - - g_log.notice() << "Attempting to verify user credentials against " << - Mantid::Kernel::ConfigService::Instance().getFacility().catalogInfo().catalogName() << std::endl; + auto catalogInfo = Kernel::ConfigService::Instance().getFacility(getProperty("FacilityName")).catalogInfo(); + if (catalogInfo.soapEndPoint().empty()) throw std::runtime_error("There is no soap end-point for the facility you have selected."); + g_log.notice() << "Attempting to verify user credentials against " << catalogInfo.catalogName() << std::endl; progress(0.5, "Verifying user credentials..."); - CatalogAlgorithmHelper().createCatalog()->login(getProperty("Username"), getProperty("Password"), soapEndPoint); + auto catalogManager = CatalogManager::Instance().create(getProperty("FacilityName")); + catalogManager->login(getProperty("Username"), getProperty("Password"), catalogInfo.soapEndPoint()); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp index 5c5c593496a0..fa811a398526 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp @@ -6,6 +6,7 @@ This algorithm disconnects the logged in user from the information catalog. #include "MantidICat/CatalogLogout.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" namespace Mantid { @@ -26,7 +27,8 @@ namespace Mantid /// execute the algorithm void CatalogLogout::exec() { - CatalogAlgorithmHelper().createCatalog()->logout(); + CatalogManager::Instance().getCatalogs()->logout(); + CatalogManager::Instance().destroyCatalogs(); } } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp index 515793b94885..e5b0326c32f5 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp @@ -1,5 +1,7 @@ #include "MantidICat/CatalogManager.h" #include "MantidAPI/CatalogFactory.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" namespace Mantid { @@ -11,15 +13,16 @@ namespace Mantid /** * Creates a new catalog and adds it to the compositeCatalog and activeCatalog list. - * @param facilityName :: The name of the facility to create a catalog for. + * @param facilityName :: The name of the facility to obtain the catalog name from. * @return A catalog for the facility specified. */ API::ICatalog_sptr CatalogManagerImpl::create(const std::string facilityName) { - auto catalog = API::CatalogFactory::Instance().create(facilityName); - m_compositeCatalog->add(catalog); - m_activeCatalogs.insert(std::make_pair("",catalog)); - return catalog; + std::string className = Kernel::ConfigService::Instance().getFacility(facilityName).catalogInfo().catalogName(); + auto catalog = API::CatalogFactory::Instance().create(className); + m_compositeCatalog->add(catalog); + m_activeCatalogs.insert(std::make_pair("",catalog)); + return catalog; } /** diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 2da62966f9f3..d4eb34aeb74d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -6,6 +6,7 @@ This algorithm retrieves logged in users investigations data from the informatio #include "MantidICat/CatalogMyDataSearch.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" namespace Mantid { @@ -30,9 +31,8 @@ namespace Mantid /// Execution method. void CatalogMyDataSearch::exec() { - // Create and use the catalog the user has specified in Facilities.xml auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogAlgorithmHelper().createCatalog()->myData(outputws); + CatalogManager::Instance().getCatalogs()->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index 54d86a066b78..4b31b428353b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -17,6 +17,7 @@ This algorithm searches for the investigations and stores the search results in #include "MantidKernel/DateValidator.h" #include "MantidKernel/PropertyWithValue.h" #include "MantidICat/CatalogAlgorithmHelper.h" +#include "MantidICat/CatalogManager.h" #include #include @@ -72,19 +73,19 @@ namespace Mantid getInputProperties(params); // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - // Create a catalog since we use it twice on execution. - API::ICatalog_sptr catalog = CatalogAlgorithmHelper().createCatalog(); + // Obtain all the active catalogs. + auto catalogs = CatalogManager::Instance().getCatalogs(); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. if (getProperty("CountOnly")) { // Set the related property needed for paging. - setProperty("NumberOfSearchResults", catalog->getNumberOfSearchResults(params)); + setProperty("NumberOfSearchResults", catalogs->getNumberOfSearchResults(params)); return; } // Search for investigations in the archives. - catalog->search(params,workspace,getProperty("Offset"),getProperty("Limit")); + catalogs->search(params,workspace,getProperty("Offset"),getProperty("Limit")); } /** From c306b0aaab65de6cc2c1bdc2e53b5281dc2acf29 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 26 Feb 2014 17:36:40 +0000 Subject: [PATCH 024/118] Removed unused headers from catalog algorithms. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp | 1 - Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp | 1 - Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp | 1 - .../Framework/ICat/src/CatalogListInvestigationTypes.cpp | 1 - Code/Mantid/Framework/ICat/src/CatalogLogin.cpp | 5 +++-- Code/Mantid/Framework/ICat/src/CatalogLogout.cpp | 1 - Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp | 1 - Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 1 - 8 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index 5cbb983407fd..3d17886eb43e 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -6,7 +6,6 @@ This algorithm retrieves the files associated to selected investigation from the #include "MantidICat/CatalogGetDataFiles.h" #include "MantidICat/CatalogManager.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidAPI/WorkspaceProperty.h" diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 25103866ea81..67afad6a3c6d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -5,7 +5,6 @@ from the information catalog and saves the search results to mantid workspace. #include "MantidICat/CatalogGetDataSets.h" #include "MantidICat/CatalogManager.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidAPI/WorkspaceProperty.h" diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 8a628b86c613..80adf995ad97 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -5,7 +5,6 @@ This algorithm retrieves the instrument names from a catalog and stores them in *WIKI*/ #include "MantidICat/CatalogListInstruments.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index 6d887984905b..e5ceafeb4a35 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -5,7 +5,6 @@ This algorithm is responsible for obtaining a list of investigation types from t *WIKI*/ #include "MantidICat/CatalogListInvestigationTypes.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp index b8d50d7579ce..ac8e19454d0d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp @@ -5,11 +5,12 @@ This algorithm connects the logged in user to the information catalog. *WIKI*/ #include "MantidICat/CatalogLogin.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/MaskedProperty.h" -#include "MantidKernel/ListValidator.h" namespace Mantid { diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp index fa811a398526..8d1936434f0f 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp @@ -5,7 +5,6 @@ This algorithm disconnects the logged in user from the information catalog. *WIKI*/ #include "MantidICat/CatalogLogout.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" namespace Mantid diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index d4eb34aeb74d..33e2eb90af1f 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -5,7 +5,6 @@ This algorithm retrieves logged in users investigations data from the informatio *WIKI*/ #include "MantidICat/CatalogMyDataSearch.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" namespace Mantid diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index 4b31b428353b..d878e56ffa41 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -16,7 +16,6 @@ This algorithm searches for the investigations and stores the search results in #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/DateValidator.h" #include "MantidKernel/PropertyWithValue.h" -#include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidICat/CatalogManager.h" #include From 9d892df7bfa7bbfb7684356939dfe9b79b5c6534 Mon Sep 17 00:00:00 2001 From: Karl Palmen Date: Thu, 27 Feb 2014 10:32:50 +0000 Subject: [PATCH 025/118] Modify MuonLoad wiki to use flowchart re #9047 Also move XML for flowchart to WorkflowAlgorithms. --- .../doc/diagrams/MuonWorkflow.xml | 0 Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp | 4 ++++ 2 files changed, 4 insertions(+) rename Code/Mantid/Framework/{DataHandling => WorkflowAlgorithms}/doc/diagrams/MuonWorkflow.xml (100%) diff --git a/Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml similarity index 100% rename from Code/Mantid/Framework/DataHandling/doc/diagrams/MuonWorkflow.xml rename to Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp index 4f23885bbcb9..6b2bc19d0aca 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp @@ -8,6 +8,10 @@ The algorithm replicates the sequence of actions undertaken by MuonAnalysis in o # Offset, crop and rebin the workspace # If the loaded data is multi-period - apply the specified operation to specified periods to get a single data set. # Use [[MuonCalculateAsymmetry]] to get the resulting workspace. + +=== Workflow === +[[File:MuonWorkflow.png]] + *WIKI*/ #include "MantidWorkflowAlgorithms/MuonLoad.h" From 754b6c4f94fe2335f8b968b8aa94ef1cbfd95cee Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 10:49:11 +0000 Subject: [PATCH 026/118] Remove getCatalogs from catalogManager. Refs #9084. - Removed use of compositeCatalog in catalogManager. The active catalogs attribute is used instead. - Removed now unnecessary methods from compositeCatalog. - Updated algorithms that use catalog manager. - Log each catalog out when destroyCatalogs is called in CatalogManager. This ensures the ICAT server knows the user has logged out. --- .../ICat/inc/MantidICat/CatalogManager.h | 6 +--- .../ICat/inc/MantidICat/CompositeCatalog.h | 5 --- .../ICat/src/CatalogGetDataFiles.cpp | 2 +- .../Framework/ICat/src/CatalogGetDataSets.cpp | 2 +- .../ICat/src/CatalogListInstruments.cpp | 2 +- .../src/CatalogListInvestigationTypes.cpp | 2 +- .../Framework/ICat/src/CatalogLogout.cpp | 1 - .../Framework/ICat/src/CatalogManager.cpp | 35 ++++++++++--------- .../ICat/src/CatalogMyDataSearch.cpp | 2 +- .../Framework/ICat/src/CatalogSearch.cpp | 2 +- .../Framework/ICat/src/CompositeCatalog.cpp | 17 --------- 11 files changed, 26 insertions(+), 50 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h index 93d870c249b7..1f43649e0d55 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h @@ -2,7 +2,7 @@ #define MANTID_ICAT_CATALOGMANAGERIMPL_H_ #include "MantidKernel/SingletonHolder.h" -#include "MantidICat/CompositeCatalog.h" +#include "MantidAPI/ICatalog.h" namespace Mantid { @@ -40,8 +40,6 @@ namespace Mantid API::ICatalog_sptr create(const std::string facilityName); /// Get a specific catalog using the sessionID. API::ICatalog_sptr getCatalog(const std::string sessionID); - /// Get a list of all active catalogs. - boost::shared_ptr getCatalogs(); /// Destroy and remove a specific catalog from the active catalogs list. void destroyCatalog(const std::string sessionID); /// Destroy all active catalogs. @@ -57,8 +55,6 @@ namespace Mantid // Holds a list of active catalogs and uses their sessionId as unique identifier. std::map m_activeCatalogs; - // Used to return the compositeCatalog that holds the created catalogs. - boost::shared_ptr m_compositeCatalog; }; #ifdef _WIN32 diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h index f1fc9688b34d..46c39eab0073 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h @@ -39,11 +39,6 @@ namespace Mantid CompositeCatalog(); /// Adds a catalog to the list of catalogs (m_catalogs) void add(const API::ICatalog_sptr catalog); - /// Remove a specific catalog from the list of catalogs. - void removeCatalogFromComposite(API::ICatalog_sptr& catalog); - /// Clear the list of catalogs. - void clearCompositeCatalog(); - /// Log the user into the catalog system. virtual void login(const std::string& username,const std::string& password,const std::string& endpoint); /// Log the user out of the catalog system. diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index 3d17886eb43e..e4c638e9f40d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -35,7 +35,7 @@ namespace Mantid void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalogs()->getDataFiles(getProperty("InvestigationId"),workspace); + CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 67afad6a3c6d..a8294fc8cb14 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -34,7 +34,7 @@ namespace Mantid void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalogs()->getDataSets(getProperty("InvestigationId"),workspace); + CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 80adf995ad97..5503b1effb0f 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -35,7 +35,7 @@ namespace Mantid void CatalogListInstruments::exec() { std::vector instruments; - CatalogManager::Instance().getCatalogs()->listInstruments(instruments); + CatalogManager::Instance().getCatalog("")->listInstruments(instruments); setProperty("InstrumentList",instruments); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index e5ceafeb4a35..0d9ca621f052 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -33,7 +33,7 @@ namespace Mantid void CatalogListInvestigationTypes::exec() { std::vector investigationTypes; - CatalogManager::Instance().getCatalogs()->listInvestigationTypes(investigationTypes); + CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); setProperty("InvestigationTypes",investigationTypes); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp index 8d1936434f0f..2c44a264ca06 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp @@ -26,7 +26,6 @@ namespace Mantid /// execute the algorithm void CatalogLogout::exec() { - CatalogManager::Instance().getCatalogs()->logout(); CatalogManager::Instance().destroyCatalogs(); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp index e5b0326c32f5..fd612dcfe78b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogManager.cpp @@ -1,4 +1,5 @@ #include "MantidICat/CatalogManager.h" +#include "MantidICat/CompositeCatalog.h" #include "MantidAPI/CatalogFactory.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/FacilityInfo.h" @@ -7,7 +8,7 @@ namespace Mantid { namespace ICat { - CatalogManagerImpl::CatalogManagerImpl() : m_activeCatalogs(), m_compositeCatalog(new CompositeCatalog()) {} + CatalogManagerImpl::CatalogManagerImpl() : m_activeCatalogs() {} CatalogManagerImpl::~CatalogManagerImpl(){} @@ -20,33 +21,33 @@ namespace Mantid { std::string className = Kernel::ConfigService::Instance().getFacility(facilityName).catalogInfo().catalogName(); auto catalog = API::CatalogFactory::Instance().create(className); - m_compositeCatalog->add(catalog); m_activeCatalogs.insert(std::make_pair("",catalog)); return catalog; } /** - * Obtain a specific catalog using the sessionID. + * Obtain a specific catalog using the sessionID, otherwise return all active catalogs. * @param sessionID :: The session to search for in the active catalogs list. - * @return A specific catalog using the sessionID. + * @return A specific catalog using the sessionID, otherwise returns all active catalogs */ API::ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string sessionID) { + if(sessionID.empty()) + { + auto composite = boost::make_shared(); + for (auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) + { + composite->add(item->second); + } + return composite; + } + auto pos = m_activeCatalogs.find(sessionID); // If the key element exists in the map we want the related catalog. if (pos != m_activeCatalogs.end()) return pos->second; else throw std::runtime_error("The session ID you have provided is invalid"); } - /** - * Obtain a list of all active catalogs. - * @return A composite catalog object as it holds and performs operations on all catalogs. - */ - boost::shared_ptr CatalogManagerImpl::getCatalogs() - { - return m_compositeCatalog; - } - /** * Destroy and remove a specific catalog from the active catalogs list and the composite catalog. * @param sessionID :: The session to search for in the active catalogs list. @@ -58,7 +59,6 @@ namespace Mantid if (pos != m_activeCatalogs.end()) { pos->second->logout(); - m_compositeCatalog->removeCatalogFromComposite((pos->second)); m_activeCatalogs.erase(pos); } } @@ -68,8 +68,11 @@ namespace Mantid */ void CatalogManagerImpl::destroyCatalogs() { - m_compositeCatalog->logout(); - m_compositeCatalog->clearCompositeCatalog(); + for (auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) + { + item->second->logout(); + } + m_activeCatalogs.clear(); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 33e2eb90af1f..32770e40ad67 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -31,7 +31,7 @@ namespace Mantid void CatalogMyDataSearch::exec() { auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalogs()->myData(outputws); + CatalogManager::Instance().getCatalog("")->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index d878e56ffa41..d7eaa68653ba 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -73,7 +73,7 @@ namespace Mantid // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); // Obtain all the active catalogs. - auto catalogs = CatalogManager::Instance().getCatalogs(); + auto catalogs = CatalogManager::Instance().getCatalog(""); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. diff --git a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp b/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp index 7cbc92fffc3f..8886b3420090 100644 --- a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp +++ b/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp @@ -15,23 +15,6 @@ namespace Mantid m_catalogs.push_back(catalog); } - /** - * Remove a specific catalog from the catalog container. - * @param catalog :: The catalog to remove from the catlaog container. - */ - void CompositeCatalog::removeCatalogFromComposite(API::ICatalog_sptr& catalog) - { - std::remove(m_catalogs.begin(),m_catalogs.end(),catalog); - } - - /** - * Clear the catalog container. - */ - void CompositeCatalog::clearCompositeCatalog() - { - m_catalogs.clear(); - } - /** * Authenticate the user against all catalogues in the container. * @param username :: The login name of the user. From a4dc6128ac5fcf8f9656327273af0b27c6872e6f Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 27 Feb 2014 11:58:48 +0000 Subject: [PATCH 027/118] re #9014: Move the reducer_singleton to scripts folder This is to allow Indirect to use the same module. And because it is not strictly related to SANS. --- Code/Mantid/scripts/{SANS => }/reducer_singleton.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Code/Mantid/scripts/{SANS => }/reducer_singleton.py (100%) diff --git a/Code/Mantid/scripts/SANS/reducer_singleton.py b/Code/Mantid/scripts/reducer_singleton.py similarity index 100% rename from Code/Mantid/scripts/SANS/reducer_singleton.py rename to Code/Mantid/scripts/reducer_singleton.py From 03f4790a470900e9695383d547a3663725d8f999 Mon Sep 17 00:00:00 2001 From: Gesner Passos Date: Thu, 27 Feb 2014 12:00:29 +0000 Subject: [PATCH 028/118] re #9014: Move ReductionStep to reducer_singleton module After discussion, this allows Indirect to use all they need to implement #9093. --- .../scripts/SANS/isis_reduction_steps.py | 45 ++++--------------- Code/Mantid/scripts/reducer_singleton.py | 31 +++++++++++++ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/Code/Mantid/scripts/SANS/isis_reduction_steps.py b/Code/Mantid/scripts/SANS/isis_reduction_steps.py index 295fbee56d52..9283c20df352 100644 --- a/Code/Mantid/scripts/SANS/isis_reduction_steps.py +++ b/Code/Mantid/scripts/SANS/isis_reduction_steps.py @@ -6,7 +6,12 @@ Most of this code is a copy-paste from SANSReduction.py, organized to be used with ReductionStep objects. The guts needs refactoring. """ -import isis_reducer +import os +import math +import copy +import re + + from mantid.kernel import Logger sanslog = Logger.get("SANS") @@ -17,12 +22,8 @@ getFilePathFromWorkspace, getWorkspaceReference, getMonitor4event, slice2histogram) import isis_instrument -import os -import math -import copy -import re -import random -import string +import isis_reducer +from reducer_singleton import ReductionStep def _issueWarning(msg): """ @@ -41,36 +42,6 @@ def _issueInfo(msg): sanslog.notice(msg) -class ReductionStep(object): - """ - Base class for reduction steps - """ - @classmethod - def delete_workspaces(cls, workspace): - """ - Delete all workspace created by this reduction step related - to the given workspace - @param workspace: workspace to delete - """ - return - - @classmethod - def _create_unique_name(cls, filepath, descriptor): - """ - Generate a unique name for an internal workspace - """ - random_str = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(5)) - return "__"+descriptor+"_"+extract_workspace_name(filepath)+"_"+random_str - - def execute(self, reducer, inputworkspace=None, outputworkspace=None): - """ - Implemented the reduction step. - @param reducer: Reducer object for which the step is executed - @param inputworkspace: Name of the workspace to apply this step to - @param outputworkspace: Name of the workspace to have as an output. If this is None it will be set to inputworkspace - """ - raise NotImplemented - class LoadRun(object): UNSET_PERIOD = -1 def __init__(self, run_spec=None, trans=False, reload=True, entry=UNSET_PERIOD): diff --git a/Code/Mantid/scripts/reducer_singleton.py b/Code/Mantid/scripts/reducer_singleton.py index 76ff6f018273..f47922674971 100644 --- a/Code/Mantid/scripts/reducer_singleton.py +++ b/Code/Mantid/scripts/reducer_singleton.py @@ -5,6 +5,37 @@ from isis_instrument import BaseInstrument + +class ReductionStep(object): + """ + Base class for reduction steps + """ + @classmethod + def delete_workspaces(cls, workspace): + """ + Delete all workspace created by this reduction step related + to the given workspace + @param workspace: workspace to delete + """ + return + + @classmethod + def _create_unique_name(cls, filepath, descriptor): + """ + Generate a unique name for an internal workspace + """ + random_str = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for x in range(5)) + return "__"+descriptor+"_"+extract_workspace_name(filepath)+"_"+random_str + + def execute(self, reducer, inputworkspace=None, outputworkspace=None): + """ + Implemented the reduction step. + @param reducer: Reducer object for which the step is executed + @param inputworkspace: Name of the workspace to apply this step to + @param outputworkspace: Name of the workspace to have as an output. If this is None it will be set to inputworkspace + """ + raise NotImplemented + class Reducer(object): """ Base reducer class. Instrument-specific reduction processes should be From 28fad4764d7ad8e6f687e697e75a4d65a0cb0316 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 12:16:46 +0000 Subject: [PATCH 029/118] Move compositeCatalog and catlaogManager to API. Refs #9084. --- Code/Mantid/Framework/API/CMakeLists.txt | 4 ++++ .../inc/MantidAPI}/CatalogManager.h | 8 ++++---- .../inc/MantidAPI}/CompositeCatalog.h | 18 +++++++++--------- .../{ICat => API}/src/CatalogManager.cpp | 14 +++++++------- .../{ICat => API}/src/CompositeCatalog.cpp | 16 ++++++++-------- Code/Mantid/Framework/ICat/CMakeLists.txt | 4 ---- .../Framework/ICat/src/CatalogGetDataFiles.cpp | 4 ++-- .../Framework/ICat/src/CatalogGetDataSets.cpp | 4 ++-- .../ICat/src/CatalogListInstruments.cpp | 4 ++-- .../ICat/src/CatalogListInvestigationTypes.cpp | 4 ++-- .../Mantid/Framework/ICat/src/CatalogLogin.cpp | 4 ++-- .../Framework/ICat/src/CatalogLogout.cpp | 4 ++-- .../Framework/ICat/src/CatalogMyDataSearch.cpp | 4 ++-- .../Framework/ICat/src/CatalogSearch.cpp | 4 ++-- .../Framework/ICat/test/CompositeCatalogTest.h | 2 +- 15 files changed, 49 insertions(+), 49 deletions(-) rename Code/Mantid/Framework/{ICat/inc/MantidICat => API/inc/MantidAPI}/CatalogManager.h (91%) rename Code/Mantid/Framework/{ICat/inc/MantidICat => API/inc/MantidAPI}/CompositeCatalog.h (82%) rename Code/Mantid/Framework/{ICat => API}/src/CatalogManager.cpp (84%) rename Code/Mantid/Framework/{ICat => API}/src/CompositeCatalog.cpp (90%) diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index fd1c917fb591..c0a1222e0ca5 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -12,9 +12,11 @@ set ( SRC_FILES src/Axis.cpp src/BoxController.cpp src/CatalogFactory.cpp + src/CatalogManager.cpp src/ChopperModel.cpp src/Column.cpp src/ColumnFactory.cpp + src/CompositeCatalog.cpp src/CompositeDomainMD.cpp src/CompositeFunction.cpp src/ConstraintFactory.cpp @@ -135,9 +137,11 @@ set ( INC_FILES inc/MantidAPI/Axis.h inc/MantidAPI/BoxController.h inc/MantidAPI/CatalogFactory.h + inc/MantidAPI/CatalogManager.h inc/MantidAPI/ChopperModel.h inc/MantidAPI/Column.h inc/MantidAPI/ColumnFactory.h + inc/MantidAPI/CompositeCatalog.h inc/MantidAPI/CompositeDomain.h inc/MantidAPI/CompositeDomainMD.h inc/MantidAPI/CompositeFunction.h diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h similarity index 91% rename from Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h rename to Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index 1f43649e0d55..b2b6f22b5bbd 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -6,7 +6,7 @@ namespace Mantid { - namespace ICat + namespace API { /** This class is a singleton and is responsible for creating, destroying, and managing catalogs. @@ -37,9 +37,9 @@ namespace Mantid { public: /// Create a new catalog, and add it to the list of active catalogs. - API::ICatalog_sptr create(const std::string facilityName); + ICatalog_sptr create(const std::string facilityName); /// Get a specific catalog using the sessionID. - API::ICatalog_sptr getCatalog(const std::string sessionID); + ICatalog_sptr getCatalog(const std::string sessionID); /// Destroy and remove a specific catalog from the active catalogs list. void destroyCatalog(const std::string sessionID); /// Destroy all active catalogs. @@ -54,7 +54,7 @@ namespace Mantid virtual ~CatalogManagerImpl(); // Holds a list of active catalogs and uses their sessionId as unique identifier. - std::map m_activeCatalogs; + std::map m_activeCatalogs; }; #ifdef _WIN32 diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h similarity index 82% rename from Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h rename to Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h index 46c39eab0073..2b5657dcbfcb 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CompositeCatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h @@ -5,7 +5,7 @@ namespace Mantid { - namespace ICat + namespace API { /** CompositeCatalog is responsible for storing and performing options on multiple catalogues. @@ -32,28 +32,28 @@ namespace Mantid File change history is stored at: . Code Documentation is available at: */ - class DLLExport CompositeCatalog : public API::ICatalog + class DLLExport CompositeCatalog : public ICatalog { public: /// Constructor CompositeCatalog(); /// Adds a catalog to the list of catalogs (m_catalogs) - void add(const API::ICatalog_sptr catalog); + void add(const ICatalog_sptr catalog); /// Log the user into the catalog system. virtual void login(const std::string& username,const std::string& password,const std::string& endpoint); /// Log the user out of the catalog system. virtual void logout(); /// Search the catalog for data. - virtual void search(const CatalogSearchParam& inputs,API::ITableWorkspace_sptr& outputws, + virtual void search(const ICat::CatalogSearchParam& inputs,ITableWorkspace_sptr& outputws, const int &offset, const int &limit); /// Obtain the number of results returned by the search method. - virtual int64_t getNumberOfSearchResults(const CatalogSearchParam& inputs); + virtual int64_t getNumberOfSearchResults(const ICat::CatalogSearchParam& inputs); /// Show the logged in user's investigations search results. - virtual void myData(API::ITableWorkspace_sptr& outputws); + virtual void myData(ITableWorkspace_sptr& outputws); /// Get datasets. - virtual void getDataSets(const std::string& investigationId,API::ITableWorkspace_sptr& outputws); + virtual void getDataSets(const std::string& investigationId,ITableWorkspace_sptr& outputws); /// Get datafiles - virtual void getDataFiles(const std::string& investigationId,API::ITableWorkspace_sptr& outputws); + virtual void getDataFiles(const std::string& investigationId,ITableWorkspace_sptr& outputws); /// Get instruments list virtual void listInstruments(std::vector& instruments); /// Get investigationtypes list @@ -62,7 +62,7 @@ namespace Mantid virtual void keepAlive(); private: - std::list m_catalogs; + std::list m_catalogs; }; } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp similarity index 84% rename from Code/Mantid/Framework/ICat/src/CatalogManager.cpp rename to Code/Mantid/Framework/API/src/CatalogManager.cpp index fd612dcfe78b..19a34cd9d5ff 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -1,12 +1,12 @@ -#include "MantidICat/CatalogManager.h" -#include "MantidICat/CompositeCatalog.h" #include "MantidAPI/CatalogFactory.h" +#include "MantidAPI/CatalogManager.h" +#include "MantidAPI/CompositeCatalog.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/FacilityInfo.h" namespace Mantid { - namespace ICat + namespace API { CatalogManagerImpl::CatalogManagerImpl() : m_activeCatalogs() {} @@ -17,11 +17,11 @@ namespace Mantid * @param facilityName :: The name of the facility to obtain the catalog name from. * @return A catalog for the facility specified. */ - API::ICatalog_sptr CatalogManagerImpl::create(const std::string facilityName) + ICatalog_sptr CatalogManagerImpl::create(const std::string facilityName) { std::string className = Kernel::ConfigService::Instance().getFacility(facilityName).catalogInfo().catalogName(); - auto catalog = API::CatalogFactory::Instance().create(className); - m_activeCatalogs.insert(std::make_pair("",catalog)); + auto catalog = CatalogFactory::Instance().create(className); + m_activeCatalogs.insert(std::make_pair(boost::lexical_cast(rand() + 10),catalog)); return catalog; } @@ -30,7 +30,7 @@ namespace Mantid * @param sessionID :: The session to search for in the active catalogs list. * @return A specific catalog using the sessionID, otherwise returns all active catalogs */ - API::ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string sessionID) + ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string sessionID) { if(sessionID.empty()) { diff --git a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp similarity index 90% rename from Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp rename to Code/Mantid/Framework/API/src/CompositeCatalog.cpp index 8886b3420090..10026b35abb6 100644 --- a/Code/Mantid/Framework/ICat/src/CompositeCatalog.cpp +++ b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp @@ -1,8 +1,8 @@ -#include "MantidICat/CompositeCatalog.h" +#include "MantidAPI/CompositeCatalog.h" namespace Mantid { - namespace ICat + namespace API { CompositeCatalog::CompositeCatalog() : m_catalogs() {} @@ -10,7 +10,7 @@ namespace Mantid * Add a catalog to the catalog container. * @param catalog :: The catalog to add to the container. */ - void CompositeCatalog::add(const API::ICatalog_sptr catalog) + void CompositeCatalog::add(const ICatalog_sptr catalog) { m_catalogs.push_back(catalog); } @@ -47,7 +47,7 @@ namespace Mantid * @param offset :: Skip this many rows and start returning rows from this point. * @param limit :: The limit of the number of rows returned by the query. */ - void CompositeCatalog::search(const CatalogSearchParam& inputs,API::ITableWorkspace_sptr& outputws, + void CompositeCatalog::search(const ICat::CatalogSearchParam& inputs,ITableWorkspace_sptr& outputws, const int &offset, const int &limit) { for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) @@ -60,7 +60,7 @@ namespace Mantid * Obtain the number of investigations to be returned by the catalog. * @return The number of investigations from the search performed. */ - int64_t CompositeCatalog::getNumberOfSearchResults(const CatalogSearchParam& inputs) + int64_t CompositeCatalog::getNumberOfSearchResults(const ICat::CatalogSearchParam& inputs) { int64_t numberOfSearchResults = 0; for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) @@ -74,7 +74,7 @@ namespace Mantid * Obtain and save the investigations that the user is an investigator of within each catalog. * @param outputws :: The workspace to store the results. */ - void CompositeCatalog::myData(API::ITableWorkspace_sptr& outputws) + void CompositeCatalog::myData(ITableWorkspace_sptr& outputws) { for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) { @@ -87,7 +87,7 @@ namespace Mantid * @param investigationId :: A unique identifier of the investigation. * @param outputws :: The workspace to store the results. */ - void CompositeCatalog::getDataSets(const std::string&investigationId,API::ITableWorkspace_sptr& outputws) + void CompositeCatalog::getDataSets(const std::string&investigationId,ITableWorkspace_sptr& outputws) { for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) { @@ -100,7 +100,7 @@ namespace Mantid * @param investigationId :: A unique identifier of the investigation. * @param outputws :: The workspace to store the results. */ - void CompositeCatalog::getDataFiles(const std::string&investigationId,API::ITableWorkspace_sptr& outputws) + void CompositeCatalog::getDataFiles(const std::string&investigationId,ITableWorkspace_sptr& outputws) { for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) { diff --git a/Code/Mantid/Framework/ICat/CMakeLists.txt b/Code/Mantid/Framework/ICat/CMakeLists.txt index 6e745a9672c5..ca86bd3e696a 100644 --- a/Code/Mantid/Framework/ICat/CMakeLists.txt +++ b/Code/Mantid/Framework/ICat/CMakeLists.txt @@ -11,8 +11,6 @@ set ( SRC_FILES src/CatalogMyDataSearch.cpp src/CatalogSearch.cpp src/CatalogSearchParam.cpp - src/CompositeCatalog.cpp - src/CatalogManager.cpp src/GSoap.cpp src/ICat3/ICat3GSoapGenerated.cpp src/ICat3/ICat3ErrorHandling.cpp @@ -39,8 +37,6 @@ set ( INC_FILES inc/MantidICat/CatalogSearchParam.h inc/MantidICat/ICatExport.h inc/MantidICat/Session.h - inc/MantidICat/CompositeCatalog.h - inc/MantidICat/CatalogManager.h inc/MantidICat/GSoap/soapserializersH.h inc/MantidICat/GSoap/soapserializersStub.h inc/MantidICat/GSoap/stdsoap2.h diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index e4c638e9f40d..7917dc72deba 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -5,8 +5,8 @@ This algorithm retrieves the files associated to selected investigation from the *WIKI*/ #include "MantidICat/CatalogGetDataFiles.h" -#include "MantidICat/CatalogManager.h" #include "MantidKernel/MandatoryValidator.h" +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/WorkspaceProperty.h" namespace Mantid @@ -35,7 +35,7 @@ namespace Mantid void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index a8294fc8cb14..749fc7fb3836 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -4,8 +4,8 @@ from the information catalog and saves the search results to mantid workspace. *WIKI*/ #include "MantidICat/CatalogGetDataSets.h" -#include "MantidICat/CatalogManager.h" #include "MantidKernel/MandatoryValidator.h" +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/WorkspaceProperty.h" namespace Mantid @@ -34,7 +34,7 @@ namespace Mantid void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 5503b1effb0f..4699b254fe9b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -5,7 +5,7 @@ This algorithm retrieves the instrument names from a catalog and stores them in *WIKI*/ #include "MantidICat/CatalogListInstruments.h" -#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" namespace Mantid @@ -35,7 +35,7 @@ namespace Mantid void CatalogListInstruments::exec() { std::vector instruments; - CatalogManager::Instance().getCatalog("")->listInstruments(instruments); + API::CatalogManager::Instance().getCatalog("")->listInstruments(instruments); setProperty("InstrumentList",instruments); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index 0d9ca621f052..c8f78d96ef0d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -5,7 +5,7 @@ This algorithm is responsible for obtaining a list of investigation types from t *WIKI*/ #include "MantidICat/CatalogListInvestigationTypes.h" -#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogManager.h" #include "MantidKernel/ArrayProperty.h" namespace Mantid @@ -33,7 +33,7 @@ namespace Mantid void CatalogListInvestigationTypes::exec() { std::vector investigationTypes; - CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); + API::CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); setProperty("InvestigationTypes",investigationTypes); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp index ac8e19454d0d..6d42e9e3f2dd 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp @@ -5,7 +5,7 @@ This algorithm connects the logged in user to the information catalog. *WIKI*/ #include "MantidICat/CatalogLogin.h" -#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogManager.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/FacilityInfo.h" #include "MantidKernel/ListValidator.h" @@ -44,7 +44,7 @@ namespace Mantid if (catalogInfo.soapEndPoint().empty()) throw std::runtime_error("There is no soap end-point for the facility you have selected."); g_log.notice() << "Attempting to verify user credentials against " << catalogInfo.catalogName() << std::endl; progress(0.5, "Verifying user credentials..."); - auto catalogManager = CatalogManager::Instance().create(getProperty("FacilityName")); + auto catalogManager = API::CatalogManager::Instance().create(getProperty("FacilityName")); catalogManager->login(getProperty("Username"), getProperty("Password"), catalogInfo.soapEndPoint()); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp index 2c44a264ca06..6ffa7e7bd4ee 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp @@ -5,7 +5,7 @@ This algorithm disconnects the logged in user from the information catalog. *WIKI*/ #include "MantidICat/CatalogLogout.h" -#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogManager.h" namespace Mantid { @@ -26,7 +26,7 @@ namespace Mantid /// execute the algorithm void CatalogLogout::exec() { - CatalogManager::Instance().destroyCatalogs(); + API::CatalogManager::Instance().destroyCatalogs(); } } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 32770e40ad67..7c25f4d447ae 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -5,7 +5,7 @@ This algorithm retrieves logged in users investigations data from the informatio *WIKI*/ #include "MantidICat/CatalogMyDataSearch.h" -#include "MantidICat/CatalogManager.h" +#include "MantidAPI/CatalogManager.h" namespace Mantid { @@ -31,7 +31,7 @@ namespace Mantid void CatalogMyDataSearch::exec() { auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - CatalogManager::Instance().getCatalog("")->myData(outputws); + API::CatalogManager::Instance().getCatalog("")->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index d7eaa68653ba..f7ed5b258195 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -12,11 +12,11 @@ This algorithm searches for the investigations and stores the search results in GCC_DIAG_ON(literal-suffix) #endif +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/DateValidator.h" #include "MantidKernel/PropertyWithValue.h" -#include "MantidICat/CatalogManager.h" #include #include @@ -73,7 +73,7 @@ namespace Mantid // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); // Obtain all the active catalogs. - auto catalogs = CatalogManager::Instance().getCatalog(""); + auto catalogs = API::CatalogManager::Instance().getCatalog(""); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. diff --git a/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h b/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h index a3ed5864ed0e..0b00035da781 100644 --- a/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h +++ b/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h @@ -3,9 +3,9 @@ #include +#include "MantidAPI/CompositeCatalog.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidICat/CatalogSearchParam.h" -#include "MantidICat/CompositeCatalog.h" #include #include From 5c20207c4ccf6885af57199239104ada7deaad03 Mon Sep 17 00:00:00 2001 From: Samuel Jackson Date: Thu, 27 Feb 2014 13:53:10 +0000 Subject: [PATCH 030/118] Refs #8281 Resize energy rebin widgets and fix tab order (again). --- .../ConvertToEnergy.ui | 165 +++++++++--------- 1 file changed, 86 insertions(+), 79 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui index 9adc27746bd7..e29ecef724d9 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ConvertToEnergy.ui @@ -2006,7 +2006,6 @@ Later steps in the process (saving, renaming) will not be done.
-
@@ -2369,47 +2368,7 @@ Later steps in the process (saving, renaming) will not be done. - - - - - - 0 - 0 - - - - - 150 - 0 - - - - - 16777215 - 16777215 - - - - 0 - - - - Centre (SofQW) - - - - - Parallelepiped (SofQW2) - - - - - Parallelepiped/Fractional Area (SofQW3) - - - - + @@ -2423,22 +2382,12 @@ Later steps in the process (saving, renaming) will not be done. - 60 + 200 16777215 - - - - - 0 - 0 - - - - @@ -2487,7 +2436,7 @@ Later steps in the process (saving, renaming) will not be done. - 60 + 200 16777215 @@ -2550,21 +2499,17 @@ Later steps in the process (saving, renaming) will not be done. + + + 43 + 0 + + Rebin Type: - - - - - 0 - 0 - - - - @@ -2598,16 +2543,6 @@ Later steps in the process (saving, renaming) will not be done. - - - - - 0 - 0 - - - - @@ -2644,7 +2579,7 @@ Later steps in the process (saving, renaming) will not be done. - 60 + 200 16777215 @@ -2673,6 +2608,76 @@ Later steps in the process (saving, renaming) will not be done.
+ + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + 0 + + + + Centre (SofQW) + + + + + Parallelepiped (SofQW2) + + + + + Parallelepiped/Fractional Area (SofQW3) + + + +
@@ -2783,7 +2788,6 @@ Later steps in the process (saving, renaming) will not be done.
-
@@ -3356,19 +3360,22 @@ Later steps in the process (saving, renaming) will not be done. trans_ckPlot trans_ckSave sqw_cbRebinType - sqw_leELow - sqw_leEWidth - sqw_leEHigh sqw_leQLow sqw_leQWidth sqw_leQHigh sqw_ckRebinE + sqw_leELow + sqw_leEWidth + sqw_leEHigh + sqw_ckVerbose sqw_cbPlotType sqw_ckSave absRunFiles absMapFile absWhiteFile pbManageDirectories + cal_ckVerbose + cal_ckSave From d8d87595c3638595f60057138219acf49dc671a1 Mon Sep 17 00:00:00 2001 From: Karl Palmen Date: Thu, 27 Feb 2014 15:53:58 +0000 Subject: [PATCH 031/118] Update flowchart MuonWorkflow re #9047 Signed-off-by: Karl Palmen --- .../Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml index 6964a28667c2..c859838cf045 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml +++ b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file From b4b6313304c3c03fd8566cfd7534b3f25ead7463 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 17:01:45 +0000 Subject: [PATCH 032/118] Added new catalog session class to API. Refs #9084. --- Code/Mantid/Framework/API/CMakeLists.txt | 2 + .../API/inc/MantidAPI/CatalogSession.h | 55 +++++++++++++++++++ .../Framework/API/src/CatalogSession.cpp | 45 +++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h create mode 100644 Code/Mantid/Framework/API/src/CatalogSession.cpp diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index c0a1222e0ca5..6e75bf7e9998 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -13,6 +13,7 @@ set ( SRC_FILES src/BoxController.cpp src/CatalogFactory.cpp src/CatalogManager.cpp + src/CatalogSession.cpp src/ChopperModel.cpp src/Column.cpp src/ColumnFactory.cpp @@ -138,6 +139,7 @@ set ( INC_FILES inc/MantidAPI/BoxController.h inc/MantidAPI/CatalogFactory.h inc/MantidAPI/CatalogManager.h + inc/MantidAPI/CatalogSession.h inc/MantidAPI/ChopperModel.h inc/MantidAPI/Column.h inc/MantidAPI/ColumnFactory.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h new file mode 100644 index 000000000000..111c2c175c97 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -0,0 +1,55 @@ +#ifndef MANTID_API_CATALOGSESSION_H_ +#define MANTID_API_CATALOGSESSION_H_ + +#include "MantidAPI/DllConfig.h" +#include "boost/shared_ptr.hpp" + +namespace Mantid +{ + namespace API + { + /** + This class is a responsible for storing session information for a specific catalog. + + @author Jay Rainey, ISIS Rutherford Appleton Laboratory + @date 27/02/2014 + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: . + Code Documentation is available at: + */ + class MANTID_API_DLL CatalogSession + { + public: + CatalogSession(const std::string &sessionID, const std::string &facility, const std::string &endpoint); + const std::string& getSessionId() const; + const std::string& getSoapEndpoint() const; + const std::string& getFacility() const; + + private: + std::string m_sessionID; + std::string m_facility; + std::string m_endpoint; + }; + + typedef boost::shared_ptr CatalogSession_sptr; + typedef boost::shared_ptr CatalogSession_const_sptr; + } +} + +#endif /* MANTID_API_CATALOGSESSION_H_ */ diff --git a/Code/Mantid/Framework/API/src/CatalogSession.cpp b/Code/Mantid/Framework/API/src/CatalogSession.cpp new file mode 100644 index 000000000000..12bfa7875611 --- /dev/null +++ b/Code/Mantid/Framework/API/src/CatalogSession.cpp @@ -0,0 +1,45 @@ +#include "MantidAPI/CatalogSession.h" +#include "MantidKernel/Logger.h" + +namespace Mantid +{ + namespace API + { + /** + * Initialise the related catalog session variables. + * @param sessionID :: The session ID generated from logging into the catalog. + * @param facility :: The facility of the catalog the user logged in to. + * @param endpoint :: The endpoint of the catalog the user logged in to. + */ + CatalogSession::CatalogSession(const std::string &sessionID, const std::string &facility, const std::string &endpoint) : + m_sessionID(sessionID), m_facility(facility), m_endpoint(endpoint) {} + + /** + * Obtain the session ID for the catalog created. + * @return The sesssion Id of the catalog created. + */ + const std::string& CatalogSession::getSessionId() const + { + return m_sessionID; + } + + /** + * Obtains the soap end-point of the catalog created. + * @return The soap end-point used to create the catalog. + */ + const std::string& CatalogSession::getSoapEndpoint() const + { + return m_endpoint; + } + + /** + * Obtain the facility of the catalog created. + * @return The facility used to create the catalog. + */ + const std::string& CatalogSession::getFacility() const + { + return m_facility; + } + + } +} From 9c33488935ca4d87909422b3027c6d7b379cc978 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 17:04:03 +0000 Subject: [PATCH 033/118] Add setSession to CatalogSession. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h | 1 + Code/Mantid/Framework/API/src/CatalogSession.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h index 111c2c175c97..9fc9739791c0 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -38,6 +38,7 @@ namespace Mantid public: CatalogSession(const std::string &sessionID, const std::string &facility, const std::string &endpoint); const std::string& getSessionId() const; + void setSessionId(const std::string &sessionID); const std::string& getSoapEndpoint() const; const std::string& getFacility() const; diff --git a/Code/Mantid/Framework/API/src/CatalogSession.cpp b/Code/Mantid/Framework/API/src/CatalogSession.cpp index 12bfa7875611..9b7b92881a6d 100644 --- a/Code/Mantid/Framework/API/src/CatalogSession.cpp +++ b/Code/Mantid/Framework/API/src/CatalogSession.cpp @@ -23,6 +23,15 @@ namespace Mantid return m_sessionID; } + /** + * Used to clear the session ID on logout. + * @param sessionID :: The value to set the session id. + */ + void CatalogSession::setSessionId(const std::string &sessionID) + { + m_sessionID = sessionID; + } + /** * Obtains the soap end-point of the catalog created. * @return The soap end-point used to create the catalog. From bdfe1d5c16945a9bf0bec58b4ded2da2b1ce7868 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 17:32:01 +0000 Subject: [PATCH 034/118] Add facility parameter to catalog login. Refs #9084. --- .../API/inc/MantidAPI/CompositeCatalog.h | 3 ++- .../Framework/API/inc/MantidAPI/ICatalog.h | 2 +- .../Framework/API/src/CompositeCatalog.cpp | 6 +++-- .../ICat/inc/MantidICat/ICat3/ICat3Catalog.h | 3 ++- .../ICat/inc/MantidICat/ICat3/ICat3Helper.h | 3 ++- .../ICat/inc/MantidICat/ICat4/ICat4Catalog.h | 3 ++- .../Framework/ICat/src/CatalogLogin.cpp | 5 ++-- .../Framework/ICat/src/ICat3/ICat3Catalog.cpp | 26 ++++++++++--------- .../Framework/ICat/src/ICat3/ICat3Helper.cpp | 17 +++++++----- .../Framework/ICat/src/ICat4/ICat4Catalog.cpp | 16 +++++++----- 10 files changed, 49 insertions(+), 35 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h index 2b5657dcbfcb..6f522ea133a8 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h @@ -40,7 +40,8 @@ namespace Mantid /// Adds a catalog to the list of catalogs (m_catalogs) void add(const ICatalog_sptr catalog); /// Log the user into the catalog system. - virtual void login(const std::string& username,const std::string& password,const std::string& endpoint); + virtual void login(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility); /// Log the user out of the catalog system. virtual void logout(); /// Search the catalog for data. diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h index 399f8630c2bb..b1a0affd8499 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h @@ -44,7 +44,7 @@ namespace Mantid /// Virtual destructor virtual ~ICatalog(){}; /// method to login to a catalog - virtual void login(const std::string&,const std::string&,const std::string&)=0; + virtual void login(const std::string&,const std::string&,const std::string&,const std::string&)=0; /// logout from catalog virtual void logout()=0; ///Search investigations diff --git a/Code/Mantid/Framework/API/src/CompositeCatalog.cpp b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp index 10026b35abb6..6556c74ad3cd 100644 --- a/Code/Mantid/Framework/API/src/CompositeCatalog.cpp +++ b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp @@ -20,12 +20,14 @@ namespace Mantid * @param username :: The login name of the user. * @param password :: The password of the user. * @param endpoint :: The endpoint url of the catalog to log in to. + * @param facility :: The facility of the catalog to log in to. */ - void CompositeCatalog::login(const std::string& username,const std::string& password,const std::string& endpoint) + void CompositeCatalog::login(const std::string& username,const std::string& password, + const std::string& endpoint, const std::string& facility) { for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) { - (*catalog)->login(username, password, endpoint); + (*catalog)->login(username, password, endpoint, facility); } } diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h index c3f56957ee6c..ebfd91d27976 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h @@ -43,7 +43,8 @@ namespace Mantid /// destructor virtual ~ICat3Catalog(); /// login to isis catalog - virtual void login(const std::string& username,const std::string& password,const std::string& url); + virtual void login(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility); /// logout from isis catalog virtual void logout(); /// search isis data diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h index 9cf56b975942..b4ff532ef128 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h @@ -78,7 +78,8 @@ namespace Mantid int64_t getNumberOfSearchResults(const CatalogSearchParam& inputs); // do login - void doLogin(const std::string& name,const std::string& password,const std::string& url); + void doLogin(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility); /// thsi method returns true if the session id is valid bool isvalidSession(); diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h index 296656e093ac..e9f688b77e79 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h @@ -43,7 +43,8 @@ namespace Mantid /// Destructor virtual ~ICat4Catalog(); /// Log the user into the catalog system. - virtual void login(const std::string& username,const std::string& password,const std::string& url); + virtual void login(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility); /// Log the user out of the catalog system. virtual void logout(); /// Search the catalog for data. diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp index 6d42e9e3f2dd..12e6994cbb02 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp @@ -44,8 +44,9 @@ namespace Mantid if (catalogInfo.soapEndPoint().empty()) throw std::runtime_error("There is no soap end-point for the facility you have selected."); g_log.notice() << "Attempting to verify user credentials against " << catalogInfo.catalogName() << std::endl; progress(0.5, "Verifying user credentials..."); - auto catalogManager = API::CatalogManager::Instance().create(getProperty("FacilityName")); - catalogManager->login(getProperty("Username"), getProperty("Password"), catalogInfo.soapEndPoint()); + std::string facility = getProperty("FacilityName"); + auto catalogManager = API::CatalogManager::Instance().create(facility); + catalogManager->login(getProperty("Username"), getProperty("Password"), catalogInfo.soapEndPoint(),facility); } } diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp index 33daef3e604c..3d8b14e4a7ea 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp @@ -12,22 +12,24 @@ namespace Mantid DECLARE_CATALOG(ICat3Catalog) /// constructor - ICat3Catalog::ICat3Catalog() : m_helper(new CICatHelper()) - { - } + ICat3Catalog::ICat3Catalog() : m_helper(new CICatHelper()) {} + /// destructor - ICat3Catalog::~ICat3Catalog() - { - } - /**This method is responsible for connecting the client application to ICat3 based catalog services - *@param username :: login name(eg. federal id) of the user - *@param password :: passowrd of the user - *@param url :: url of the user + ICat3Catalog::~ICat3Catalog() {} + + /** + * Authenticate the user against all catalogues in the container. + * @param username :: The login name of the user. + * @param password :: The password of the user. + * @param endpoint :: The endpoint url of the catalog to log in to. + * @param facility :: The facility of the catalog to log in to. */ - void ICat3Catalog::login(const std::string& username,const std::string& password,const std::string& url) + void ICat3Catalog::login(const std::string& username,const std::string& password, + const std::string& endpoint, const std::string& facility) { - m_helper->doLogin(username,password,url); + m_helper->doLogin(username,password,endpoint,facility); } + /// This method disconnects the client application from ICat3 based catalog services void ICat3Catalog::logout() { diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index 030cc337f6a8..7b477b56161a 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -896,15 +896,18 @@ namespace Mantid } - /**This method uses ICat API login to connect to catalog - *@param name :: login name of the user - *@param password :: of the user - *@param url :: endpoint url of the catalog + /** + * Authenticate the user against all catalogues in the container. + * @param username :: The login name of the user. + * @param password :: The password of the user. + * @param endpoint :: The endpoint url of the catalog to log in to. + * @param facility :: The facility of the catalog to log in to. */ - void CICatHelper::doLogin(const std::string& name,const std::string& password,const std::string & url) + void CICatHelper::doLogin(const std::string& username,const std::string& password, + const std::string& endpoint, const std::string& facility) { // Store the soap end-point in the session for use later. - ICat::Session::Instance().setSoapEndPoint(url); + ICat::Session::Instance().setSoapEndPoint(endpoint); // Obtain the ICAT proxy that has been securely set, including soap-endpoint. ICATPortBindingProxy icat; @@ -917,7 +920,7 @@ namespace Mantid ns1__login login; ns1__loginResponse loginResponse; - std::string userName(name); + std::string userName(username); std::string passWord(password); login.username = &userName; login.password = &passWord; diff --git a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp index 33e6c4c79643..42866b826201 100644 --- a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp @@ -21,15 +21,17 @@ namespace Mantid ICat4Catalog::~ICat4Catalog() { } /** - * Uses ICat API login to connect to catalog. - * @param username :: login name(E.g. federal id) of the user - * @param password :: password of the user - * @param url :: endpoint url of the catalog + * Authenticate the user against all catalogues in the container. + * @param username :: The login name of the user. + * @param password :: The password of the user. + * @param endpoint :: The endpoint url of the catalog to log in to. + * @param facility :: The facility of the catalog to log in to. */ - void ICat4Catalog::login(const std::string& username, const std::string& password, const std::string& url) + void ICat4Catalog::login(const std::string& username,const std::string& password, + const std::string& endpoint, const std::string& facility) { // Store the soap end-point in the session for use later. - ICat::Session::Instance().setSoapEndPoint(url); + ICat::Session::Instance().setSoapEndPoint(endpoint); // Securely set, including soap-endpoint. ICat4::ICATPortBindingProxy icat; setICATProxySettings(icat); @@ -47,7 +49,7 @@ namespace Mantid // Name of the authentication plugin in use. std::string plugin; - if (url.find("sns") != std::string::npos) { + if (endpoint.find("sns") != std::string::npos) { plugin = std::string("ldap"); } else { plugin = std::string("uows"); From 2c3772edd220e899772654e8822de5b1f3adceb6 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 17:49:24 +0000 Subject: [PATCH 035/118] Pass parameters by reference in CatalogManager. Refs #9084. - I have to create and pass in an empty string to getCatalog (instead of "") otherwise linker errors occur. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h | 8 ++++---- .../Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h | 2 +- Code/Mantid/Framework/API/src/CatalogManager.cpp | 6 +++--- Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp | 3 ++- .../Framework/ICat/src/CatalogListInvestigationTypes.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 3 ++- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index b2b6f22b5bbd..2c1fac0c04a1 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -33,15 +33,15 @@ namespace Mantid File change history is stored at: . Code Documentation is available at: */ - class DLLExport CatalogManagerImpl + class MANTID_API_DLL CatalogManagerImpl { public: /// Create a new catalog, and add it to the list of active catalogs. - ICatalog_sptr create(const std::string facilityName); + ICatalog_sptr create(const std::string &facilityName); /// Get a specific catalog using the sessionID. - ICatalog_sptr getCatalog(const std::string sessionID); + ICatalog_sptr getCatalog(const std::string &sessionID); /// Destroy and remove a specific catalog from the active catalogs list. - void destroyCatalog(const std::string sessionID); + void destroyCatalog(const std::string &sessionID); /// Destroy all active catalogs. void destroyCatalogs(); diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h index 6f522ea133a8..e8aeda0c19ed 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h @@ -32,7 +32,7 @@ namespace Mantid File change history is stored at: . Code Documentation is available at: */ - class DLLExport CompositeCatalog : public ICatalog + class MANTID_API_DLL CompositeCatalog : public ICatalog { public: /// Constructor diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index 19a34cd9d5ff..2b23121bd7d1 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -17,7 +17,7 @@ namespace Mantid * @param facilityName :: The name of the facility to obtain the catalog name from. * @return A catalog for the facility specified. */ - ICatalog_sptr CatalogManagerImpl::create(const std::string facilityName) + ICatalog_sptr CatalogManagerImpl::create(const std::string &facilityName) { std::string className = Kernel::ConfigService::Instance().getFacility(facilityName).catalogInfo().catalogName(); auto catalog = CatalogFactory::Instance().create(className); @@ -30,7 +30,7 @@ namespace Mantid * @param sessionID :: The session to search for in the active catalogs list. * @return A specific catalog using the sessionID, otherwise returns all active catalogs */ - ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string sessionID) + ICatalog_sptr CatalogManagerImpl::getCatalog(const std::string &sessionID) { if(sessionID.empty()) { @@ -52,7 +52,7 @@ namespace Mantid * Destroy and remove a specific catalog from the active catalogs list and the composite catalog. * @param sessionID :: The session to search for in the active catalogs list. */ - void CatalogManagerImpl::destroyCatalog(const std::string sessionID) + void CatalogManagerImpl::destroyCatalog(const std::string& sessionID) { auto pos = m_activeCatalogs.find(sessionID); diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index 7917dc72deba..af5b20f2e514 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -35,7 +35,8 @@ namespace Mantid void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); + const std::string sessionID = ""; + API::CatalogManager::Instance().getCatalog(sessionID)->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 749fc7fb3836..7e7d8e2369e4 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -34,7 +34,8 @@ namespace Mantid void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); + const std::string sessionID = ""; + API::CatalogManager::Instance().getCatalog(sessionID)->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 4699b254fe9b..c31d0bff05e9 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -35,7 +35,8 @@ namespace Mantid void CatalogListInstruments::exec() { std::vector instruments; - API::CatalogManager::Instance().getCatalog("")->listInstruments(instruments); + const std::string sessionID = ""; + API::CatalogManager::Instance().getCatalog(sessionID)->listInstruments(instruments); setProperty("InstrumentList",instruments); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index c8f78d96ef0d..a86ca9c5dc5b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -33,7 +33,8 @@ namespace Mantid void CatalogListInvestigationTypes::exec() { std::vector investigationTypes; - API::CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); + const std::string sessionID = ""; + API::CatalogManager::Instance().getCatalog(sessionID)->listInvestigationTypes(investigationTypes); setProperty("InvestigationTypes",investigationTypes); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 7c25f4d447ae..96477d2bc2f6 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -31,7 +31,8 @@ namespace Mantid void CatalogMyDataSearch::exec() { auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->myData(outputws); + const std::string sessionID = ""; + API::CatalogManager::Instance().getCatalog(sessionID)->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index f7ed5b258195..5381058372bd 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -73,7 +73,8 @@ namespace Mantid // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); // Obtain all the active catalogs. - auto catalogs = API::CatalogManager::Instance().getCatalog(""); + const std::string sessionID = ""; + auto catalogs = API::CatalogManager::Instance().getCatalog(sessionID); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. From 3a2216adbb9f3a3eacf96d3a4db1c411e3f47583 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 18:02:43 +0000 Subject: [PATCH 036/118] Update login method to return a session. Refs #9084. - Throw exception in the compositeCatalog for the login method as it no longer performs the correct composite functionality. (It could not return all the sessions for each catalog the user logs in to, just the last.) --- .../Framework/API/inc/MantidAPI/CompositeCatalog.h | 2 +- Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h | 3 ++- Code/Mantid/Framework/API/src/CompositeCatalog.cpp | 11 ++++++----- .../ICat/inc/MantidICat/ICat3/ICat3Catalog.h | 2 +- .../ICat/inc/MantidICat/ICat4/ICat4Catalog.h | 2 +- Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp | 2 +- Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h index e8aeda0c19ed..e988528e8522 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CompositeCatalog.h @@ -40,7 +40,7 @@ namespace Mantid /// Adds a catalog to the list of catalogs (m_catalogs) void add(const ICatalog_sptr catalog); /// Log the user into the catalog system. - virtual void login(const std::string& username,const std::string& password, + virtual CatalogSession_sptr login(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility); /// Log the user out of the catalog system. virtual void logout(); diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h b/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h index b1a0affd8499..533cf7c61a2d 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ICatalog.h @@ -2,6 +2,7 @@ #define MANTID_API_ICATLOG_H_ #include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/CatalogSession.h" namespace Mantid { @@ -44,7 +45,7 @@ namespace Mantid /// Virtual destructor virtual ~ICatalog(){}; /// method to login to a catalog - virtual void login(const std::string&,const std::string&,const std::string&,const std::string&)=0; + virtual CatalogSession_sptr login(const std::string&,const std::string&,const std::string&,const std::string&)=0; /// logout from catalog virtual void logout()=0; ///Search investigations diff --git a/Code/Mantid/Framework/API/src/CompositeCatalog.cpp b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp index 6556c74ad3cd..c648f61b5130 100644 --- a/Code/Mantid/Framework/API/src/CompositeCatalog.cpp +++ b/Code/Mantid/Framework/API/src/CompositeCatalog.cpp @@ -22,13 +22,14 @@ namespace Mantid * @param endpoint :: The endpoint url of the catalog to log in to. * @param facility :: The facility of the catalog to log in to. */ - void CompositeCatalog::login(const std::string& username,const std::string& password, + CatalogSession_sptr CompositeCatalog::login(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { - for(auto catalog = m_catalogs.begin(); catalog != m_catalogs.end(); ++catalog) - { - (*catalog)->login(username, password, endpoint, facility); - } + UNUSED_ARG(username); + UNUSED_ARG(password); + UNUSED_ARG(endpoint); + UNUSED_ARG(facility); + throw std::runtime_error("You cannot log into multiple catalogs at the same time."); } /** diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h index ebfd91d27976..03c1a1f1d8a0 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Catalog.h @@ -43,7 +43,7 @@ namespace Mantid /// destructor virtual ~ICat3Catalog(); /// login to isis catalog - virtual void login(const std::string& username,const std::string& password, + virtual API::CatalogSession_sptr login(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility); /// logout from isis catalog virtual void logout(); diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h index e9f688b77e79..eab1a2c8eb8b 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h @@ -43,7 +43,7 @@ namespace Mantid /// Destructor virtual ~ICat4Catalog(); /// Log the user into the catalog system. - virtual void login(const std::string& username,const std::string& password, + virtual API::CatalogSession_sptr login(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility); /// Log the user out of the catalog system. virtual void logout(); diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp index 3d8b14e4a7ea..48e3df155c27 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp @@ -24,7 +24,7 @@ namespace Mantid * @param endpoint :: The endpoint url of the catalog to log in to. * @param facility :: The facility of the catalog to log in to. */ - void ICat3Catalog::login(const std::string& username,const std::string& password, + API::CatalogSession_sptr ICat3Catalog::login(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { m_helper->doLogin(username,password,endpoint,facility); diff --git a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp index 42866b826201..d862eeb3cc93 100644 --- a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp @@ -27,7 +27,7 @@ namespace Mantid * @param endpoint :: The endpoint url of the catalog to log in to. * @param facility :: The facility of the catalog to log in to. */ - void ICat4Catalog::login(const std::string& username,const std::string& password, + API::CatalogSession_sptr ICat4Catalog::login(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { // Store the soap end-point in the session for use later. From cb60dc4718c70b655793f029f67986f4384742bc Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Thu, 27 Feb 2014 18:35:33 +0000 Subject: [PATCH 037/118] Use CatalogSession in ICat4Catalog. Refs #9084. --- .../ICat/inc/MantidICat/ICat4/ICat4Catalog.h | 7 +- .../Framework/ICat/src/ICat4/ICat4Catalog.cpp | 95 +++++++++---------- 2 files changed, 49 insertions(+), 53 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h index eab1a2c8eb8b..bb6c27c556ae 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat4/ICat4Catalog.h @@ -4,7 +4,6 @@ #include "MantidAPI/ICatalog.h" #include "MantidAPI/ICatalogInfoService.h" #include "MantidAPI/TableRow.h" -#include "MantidKernel/Logger.h" #include "MantidICat/CatalogSearchParam.h" namespace Mantid @@ -39,9 +38,7 @@ namespace Mantid { public: /// Constructor - ICat4Catalog():g_log(Kernel::Logger::get("ICat4Catalog")) {} - /// Destructor - virtual ~ICat4Catalog(); + ICat4Catalog(); /// Log the user into the catalog system. virtual API::CatalogSession_sptr login(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility); @@ -96,6 +93,8 @@ namespace Mantid // Reference to the logger class. Kernel::Logger& g_log; + // Stores the session details for a specific catalog. + API::CatalogSession_sptr m_session; /** * Template method to save data to table workspace diff --git a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp index d862eeb3cc93..6f2947e77374 100644 --- a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp @@ -2,10 +2,10 @@ #include "MantidAPI/Progress.h" #include "MantidICat/ICat4/GSoapGenerated/ICat4ICATPortBindingProxy.h" #include "MantidICat/ICat4/ICat4Catalog.h" -#include "MantidICat/Session.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/DateAndTime.h" #include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/Logger.h" #include "MantidKernel/Strings.h" namespace Mantid @@ -17,8 +17,7 @@ namespace Mantid DECLARE_CATALOG(ICat4Catalog) - /// Destructor - ICat4Catalog::~ICat4Catalog() { } + ICat4Catalog::ICat4Catalog() : g_log(Kernel::Logger::get("ICat4Catalog")), m_session() {} /** * Authenticate the user against all catalogues in the container. @@ -30,15 +29,14 @@ namespace Mantid API::CatalogSession_sptr ICat4Catalog::login(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { - // Store the soap end-point in the session for use later. - ICat::Session::Instance().setSoapEndPoint(endpoint); + // Created the session object here in order to set the endpoint, which is used in setICATProxySettings. + // We can then manually set the sessionID later if it exists. + m_session = boost::make_shared("",facility,endpoint); + // Securely set, including soap-endpoint. ICat4::ICATPortBindingProxy icat; setICATProxySettings(icat); - // Output the soap end-point in use for debugging purposes. - g_log.debug() << "The ICAT soap end-point is: " << icat.soap_endpoint << std::endl; - // Used to authenticate the user. ns1__login login; ns1__loginResponse loginResponse; @@ -81,14 +79,14 @@ namespace Mantid if (result == 0) { - std::string session_id = *(loginResponse.return_); - ICat::Session::Instance().setSessionId(session_id); - ICat::Session::Instance().setUserName(userName); + m_session->setSessionId(*(loginResponse.return_)); } else { throwErrorMessage(icat); } + // Will not reach here if user cannot log in (e.g. no session is created). + return m_session; } /** @@ -102,14 +100,14 @@ namespace Mantid ns1__logout request; ns1__logoutResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; int result = icat.logout(&request,&response); if(result == 0) { - Session::Instance().setSessionId(""); + m_session->setSessionId(""); } else { @@ -278,8 +276,8 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; request.query = &query; int result = icat.search(&request, &response); @@ -306,9 +304,6 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = buildSearchQuery(inputs); if (query.empty()) throw std::runtime_error("You have not input any terms to search for."); @@ -316,6 +311,9 @@ namespace Mantid query.insert(0, "SELECT COUNT(DISTINCT inves)"); request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + g_log.debug() << "The paging search query in ICat4Catalog::getNumberOfSearchResults is: \n" << query << std::endl; int result = icat.search(&request, &response); @@ -349,10 +347,11 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); // Prevents any calls to myData from hanging due to sending a request to icat without a session ID. - if (sessionID.empty()) return; - request.sessionId = &sessionID; + if (m_session->getSessionId().empty()) return; + + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; std::string query = "Investigation INCLUDE InvestigationInstrument, Instrument, InvestigationParameter <-> InvestigationUser <-> User[name = :user]"; request.query = &query; @@ -449,12 +448,12 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = "Datafile <-> Dataset <-> Investigation[name = '" + investigationId + "']"; request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + g_log.debug() << "ICat4Catalog::getDataSets -> { " << query << " }" << std::endl; int result = icat.search(&request, &response); @@ -511,12 +510,12 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = "Datafile <-> Dataset <-> Investigation[name = '" + investigationId + "']"; request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + g_log.debug() << "The query for ICat4Catalog::getDataSets is:\n" << query << std::endl; int result = icat.search(&request, &response); @@ -588,12 +587,12 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = "Instrument.fullName ORDER BY fullName"; request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + int result = icat.search(&request, &response); if (result == 0) @@ -629,12 +628,12 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = "InvestigationType.name ORDER BY name"; request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + int result = icat.search(&request, &response); if (result == 0) @@ -671,12 +670,12 @@ namespace Mantid ns1__get request; ns1__getResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; + std::string query = "Datafile"; + request.query = &query; + request.primaryKey = fileID; - std::string query = "Datafile"; - request.query = &query; - request.primaryKey = fileID; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; int result = icat.get(&request, &response); @@ -709,10 +708,10 @@ namespace Mantid const std::string ICat4Catalog::getDownloadURL(const long long & fileID) { // Obtain the URL from the Facilities.xml file. - std::string url = ConfigService::Instance().getFacility().catalogInfo().externalDownloadURL(); + std::string url = ConfigService::Instance().getFacility(m_session->getFacility()).catalogInfo().externalDownloadURL(); // Set the REST features of the URL. - std::string session = "sessionId=" + Session::Instance().getSessionId(); + std::string session = "sessionId=" + m_session->getSessionId(); std::string datafile = "&datafileIds=" + boost::lexical_cast(fileID); std::string outname = "&outname=" + boost::lexical_cast(fileID); @@ -733,11 +732,10 @@ namespace Mantid const std::string &investigationID, const std::string &createFileName, const std::string &dataFileDescription) { // Obtain the URL from the Facilities.xml file. - std::string url = ConfigService::Instance().getFacility().catalogInfo().externalDownloadURL(); + std::string url = ConfigService::Instance().getFacility(m_session->getFacility()).catalogInfo().externalDownloadURL(); - std::string sessionID = Session::Instance().getSessionId(); // Set the elements of the URL. - std::string session = "sessionId=" + sessionID; + std::string session = "sessionId=" + m_session->getSessionId(); std::string name = "&name=" + createFileName; std::string datasetId = "&datasetId=" + boost::lexical_cast(getDatasetId(investigationID)); std::string description = "&description=" + dataFileDescription; @@ -762,11 +760,10 @@ namespace Mantid ns1__search request; ns1__searchResponse response; - std::string sessionID = Session::Instance().getSessionId(); - request.sessionId = &sessionID; - std::string query = "Dataset <-> Investigation[name = '" + investigationID + "']"; request.query = &query; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; g_log.debug() << "The query performed to obtain a dataset from an investigation" << " id in ICat4Catalog::getDatasetIdFromFileName is:\n" << query << std::endl; @@ -884,9 +881,9 @@ namespace Mantid { // The soapEndPoint is only set when the user logs into the catalog. // If it's not set the correct error is returned (invalid sessionID) from the ICAT server. - if (ICat::Session::Instance().getSoapEndPoint().empty()) return; + if (m_session->getSoapEndpoint().empty()) return; // Set the soap-endpoint of the catalog we want to use. - icat.soap_endpoint = ICat::Session::Instance().getSoapEndPoint().c_str(); + icat.soap_endpoint = m_session->getSoapEndpoint().c_str(); // Sets SSL authentication scheme setSSLContext(icat); } From 830277c12afcecd268e31862f90fd49139285c1a Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 09:57:26 +0000 Subject: [PATCH 038/118] Removed unnecessary sessionID in catalog algorithms. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp | 3 +-- Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp | 3 +-- Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp | 3 +-- .../Framework/ICat/src/CatalogListInvestigationTypes.cpp | 3 +-- Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp | 3 +-- Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index af5b20f2e514..7917dc72deba 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -35,8 +35,7 @@ namespace Mantid void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - const std::string sessionID = ""; - API::CatalogManager::Instance().getCatalog(sessionID)->getDataFiles(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 7e7d8e2369e4..749fc7fb3836 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -34,8 +34,7 @@ namespace Mantid void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - const std::string sessionID = ""; - API::CatalogManager::Instance().getCatalog(sessionID)->getDataSets(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index c31d0bff05e9..4699b254fe9b 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -35,8 +35,7 @@ namespace Mantid void CatalogListInstruments::exec() { std::vector instruments; - const std::string sessionID = ""; - API::CatalogManager::Instance().getCatalog(sessionID)->listInstruments(instruments); + API::CatalogManager::Instance().getCatalog("")->listInstruments(instruments); setProperty("InstrumentList",instruments); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index a86ca9c5dc5b..c8f78d96ef0d 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -33,8 +33,7 @@ namespace Mantid void CatalogListInvestigationTypes::exec() { std::vector investigationTypes; - const std::string sessionID = ""; - API::CatalogManager::Instance().getCatalog(sessionID)->listInvestigationTypes(investigationTypes); + API::CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); setProperty("InvestigationTypes",investigationTypes); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 96477d2bc2f6..7c25f4d447ae 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -31,8 +31,7 @@ namespace Mantid void CatalogMyDataSearch::exec() { auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - const std::string sessionID = ""; - API::CatalogManager::Instance().getCatalog(sessionID)->myData(outputws); + API::CatalogManager::Instance().getCatalog("")->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index 5381058372bd..f7ed5b258195 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -73,8 +73,7 @@ namespace Mantid // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); // Obtain all the active catalogs. - const std::string sessionID = ""; - auto catalogs = API::CatalogManager::Instance().getCatalog(sessionID); + auto catalogs = API::CatalogManager::Instance().getCatalog(""); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. From cf3396bea3779b3cb033723de52852b69e41c186 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 11:21:39 +0000 Subject: [PATCH 039/118] Updated ICat3Catalog to use new session class. Refs #9084. - Made login method return the new session. - Removed destructor from ICat3Helper. - Removed unnecessary method `setReqParam` from ICat3Helper. - Removed invalid `isvailidSession` (it never makes a reques to verify the session) - Updated `listInstruments` and `listInvestigionTypes to __append__ to the list rather than reassigning it entirely. --- .../ICat/inc/MantidICat/ICat3/ICat3Helper.h | 29 +- .../Framework/ICat/src/ICat3/ICat3Catalog.cpp | 4 +- .../Framework/ICat/src/ICat3/ICat3Helper.cpp | 275 +++++------------- 3 files changed, 86 insertions(+), 222 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h index b4ff532ef128..de4195c24c70 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h @@ -3,11 +3,10 @@ #include "MantidICat/ICat3/GSoapGenerated/ICat3ICATPortBindingProxy.h" +#include "MantidICat/CatalogSearchParam.h" +#include "MantidAPI/CatalogSession.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/TableRow.h" -#include "MantidKernel/Logger.h" -#include "MantidICat/CatalogSearchParam.h" - namespace Mantid { @@ -44,19 +43,16 @@ namespace Mantid public: /// constructor - CICatHelper() : g_log(Kernel::Logger::get("CICatHelper")) - {} - /// destructor - ~CICatHelper(){} + CICatHelper(); /// search method int doSearch(ICat3::ICATPortBindingProxy& icat,boost::shared_ptr& request,ICat3::ns1__searchByAdvancedResponse& response); /// calls getInvestigationIncludes api's - int getDataFiles(long long invId,ICat3::ns1__investigationInclude include,API::ITableWorkspace_sptr& responsews_sptr); + void getDataFiles(long long invId,ICat3::ns1__investigationInclude include,API::ITableWorkspace_sptr& responsews_sptr); /// this method calls Icat api getInvestigationIncludes and returns datasets for the given investigation id. - int doDataSetsSearch(long long invId,ICat3::ns1__investigationInclude include,API::ITableWorkspace_sptr& responsews_sptr); + void doDataSetsSearch(long long invId,ICat3::ns1__investigationInclude include,API::ITableWorkspace_sptr& responsews_sptr); /// This method lists the isntruments void listInstruments(std::vector& instruments); @@ -78,12 +74,9 @@ namespace Mantid int64_t getNumberOfSearchResults(const CatalogSearchParam& inputs); // do login - void doLogin(const std::string& username,const std::string& password, + API::CatalogSession_sptr doLogin(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility); - /// thsi method returns true if the session id is valid - bool isvalidSession(); - /// get the url of the given file id const std::string getdownloadURL(const long long& fileId); @@ -93,10 +86,6 @@ namespace Mantid private: - /// This method sets the request parameters for investigation includes. - void setReqParamforInvestigationIncludes(long long invstId,ICat3::ns1__investigationInclude include, - ICat3::ns1__getInvestigationIncludes& request); - ///This method saves the file search response to table workspace API::ITableWorkspace_sptr saveFileSearchResponse(const ICat3::ns1__searchByAdvancedResponse& response); @@ -111,10 +100,6 @@ namespace Mantid /// This method saves Datasets to a table workspace void saveDataSets(const ICat3::ns1__getInvestigationIncludesResponse& response,API::ITableWorkspace_sptr& outputws); - /// This method sets the request parameters - void setReqparamforlistInstruments(ICat3::ns1__listInstruments& request); - - /// This method creates table workspace API::ITableWorkspace_sptr createTableWorkspace(); @@ -158,6 +143,8 @@ namespace Mantid } private: Kernel::Logger& g_log; ///< reference to the logger class + // Stores the session details for a specific catalog. + API::CatalogSession_sptr m_session; }; diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp index 48e3df155c27..3003fa4ce2cd 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Catalog.cpp @@ -1,6 +1,5 @@ #include "MantidICat/ICat3/ICat3Catalog.h" #include "MantidAPI/CatalogFactory.h" -#include "MantidICat/Session.h" #include "MantidAPI/Progress.h" #include "MantidAPI/AnalysisDataService.h" @@ -27,14 +26,13 @@ namespace Mantid API::CatalogSession_sptr ICat3Catalog::login(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { - m_helper->doLogin(username,password,endpoint,facility); + return m_helper->doLogin(username,password,endpoint,facility); } /// This method disconnects the client application from ICat3 based catalog services void ICat3Catalog::logout() { m_helper->doLogout(); - Session::Instance().setSessionId("");//clearing the session id saved to Mantid after log out } /*This method returns the logged in user's investigations data . diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index 7b477b56161a..b5aa0a033852 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -4,8 +4,8 @@ GCC_DIAG_OFF(literal-suffix) #endif #include "MantidICat/ICat3/ICat3Helper.h" -#include "MantidICat/Session.h" #include "MantidICat/ICat3/ICat3ErrorHandling.h" +#include "MantidKernel/Logger.h" #include #include #include @@ -18,6 +18,8 @@ namespace Mantid using namespace API; using namespace ICat3; + CICatHelper::CICatHelper() : g_log(Kernel::Logger::get("CICatHelper")), m_session() {} + /* This method calls ICat API searchbydavanced and do the basic run search * @param icat :: Proxy object for ICat * @param request :: request object @@ -251,20 +253,6 @@ namespace Mantid return outputws; } - /** - * This method sets the request parameters for the investigations includes - * @param invstId :: investigation id - * @param include :: enum parameter to retrieve dat from DB - * @param request :: request object - */ - void CICatHelper::setReqParamforInvestigationIncludes(long long invstId,ns1__investigationInclude include,ns1__getInvestigationIncludes& request) - { - //get the sessionid which is cached in session class during login - *request.sessionId=Session::Instance().getSessionId();; - *request.investigationInclude=include; - *request.investigationId=invstId; - - } /** * This method calls ICat API getInvestigationIncludes and returns investigation details for a given investigation Id * @param invstId :: investigation id @@ -272,47 +260,30 @@ namespace Mantid * @param responsews_sptr :: table workspace to save the response data * @returns zero if success otherwise error code */ - int CICatHelper::getDataFiles(long long invstId,ns1__investigationInclude include, + void CICatHelper::getDataFiles(long long invstId,ns1__investigationInclude include, API::ITableWorkspace_sptr& responsews_sptr) { - //ICAt proxy object ICATPortBindingProxy icat; setICATProxySettings(icat); ns1__getInvestigationIncludes request; - //get the sessionid which is cached in session class during login - boost::shared_ptrsessionId_sptr(new std::string); - request.sessionId=sessionId_sptr.get(); - - // enum include - boost::shared_ptrinvstInculde_sptr(new ns1__investigationInclude); - request.investigationInclude=invstInculde_sptr.get(); + ns1__getInvestigationIncludesResponse response; - request.investigationId=new LONG64; - setReqParamforInvestigationIncludes(invstId,include,request); + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + LONG64 investigationID = invstId; + request.investigationId= &investigationID; + request.investigationInclude = &include; - ns1__getInvestigationIncludesResponse response; - int ret_advsearch=icat.getInvestigationIncludes(&request,&response); - if(ret_advsearch!=0) - { - CErrorHandling::throwErrorMessages(icat); - } - std::stringstream stream; - stream<sessionId_sptr(new std::string); - request.sessionId=sessionId_sptr.get(); - - // enum include - boost::shared_ptrinvstInculde_sptr(new ns1__investigationInclude); - request.investigationInclude=invstInculde_sptr.get(); + ns1__getInvestigationIncludesResponse response; - request.investigationId=new LONG64; - setReqParamforInvestigationIncludes(invstId,include,request); + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + request.investigationInclude = &include; + LONG64 investigationID = invstId; + request.investigationId = &investigationID; - //response object - ns1__getInvestigationIncludesResponse response; - // Calling Icat api - int ret_advsearch=icat.getInvestigationIncludes(&request,&response); - if(ret_advsearch!=0) - { - CErrorHandling::throwErrorMessages(icat); - } - std::stringstream stream; - stream<datasetCollection.empty()) - { - g_log.information()<<"No datasets exists in the ICat database for the inevstigation id "+ stream.str()<& instruments) { - //ICAt proxy object ICATPortBindingProxy icat; setICATProxySettings(icat); ns1__listInstruments request; - //get the sessionid which is cached in session class during login - boost::shared_ptrsessionId_sptr(new std::string); - request.sessionId=sessionId_sptr.get(); - //setting the request parameters - setReqparamforlistInstruments(request); - - // response object ns1__listInstrumentsResponse response; - int ret=icat.listInstruments(&request,&response); - if(ret!=0) + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + + int result = icat.listInstruments(&request,&response); + + if (result == 0) { - // - if(isvalidSession()) + for(unsigned i = 0; i < response.return_.size(); ++i) { - CErrorHandling::throwErrorMessages(icat); + instruments.push_back(response.return_[i]); } - else - { - throw SessionException("Please login to the information catalog using the login dialog provided."); - } - } - if(response.return_.empty()) + else { - g_log.error()<<"Instruments List is empty"<& investTypes) + void CICatHelper::listInvestigationTypes(std::vector& investTypes) { - //ICAt proxy object ICATPortBindingProxy icat; setICATProxySettings(icat); ns1__listInvestigationTypes request; - //get the sessionid which is cached in session class during login - boost::shared_ptrsessionId_sptr(new std::string); - request.sessionId=sessionId_sptr.get(); - *request.sessionId=Session::Instance().getSessionId(); - - // response object ns1__listInvestigationTypesResponse response; - int ret=icat.listInvestigationTypes(&request,&response); - if(ret!=0) + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + + int result = icat.listInvestigationTypes(&request,&response); + + if (result == 0) { - // - if(isvalidSession()) - { - CErrorHandling::throwErrorMessages(icat); - } - else + for(unsigned i = 0; i < response.return_.size(); ++i) { - throw SessionException("Please login to the information catalog using the login dialog provided."); + investTypes.push_back(response.return_[i]); } } - if(response.return_.empty()) + else { - g_log.information()<<"Investigation types is empty"< sessionId_sptr(new std::string); - *sessionId_sptr=Session::Instance().getSessionId(); - request.sessionId=sessionId_sptr.get(); + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; int ret=icat.logout(&request,&response); if(ret!=0) { throw std::runtime_error("You are not currently logged into the cataloging system."); } - + m_session->setSessionId(""); return ret; } @@ -653,9 +570,8 @@ namespace Mantid ns1__getMyInvestigationsIncludes request; ns1__getMyInvestigationsIncludesResponse response; - boost::shared_ptr sessionId_sptr(new std::string); - *sessionId_sptr=Session::Instance().getSessionId(); - request.sessionId=sessionId_sptr.get(); + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; // investigation include boost::shared_ptrinvstInculde_sptr(new ns1__investigationInclude); request.investigationInclude=invstInculde_sptr.get(); @@ -664,14 +580,7 @@ namespace Mantid int ret=icat.getMyInvestigationsIncludes(&request,&response); if(ret!=0) { - if(isvalidSession()) - { - CErrorHandling::throwErrorMessages(icat); - } - else - { - throw SessionException("Please login to the information catalog using the login dialog provided."); - } + CErrorHandling::throwErrorMessages(icat); } if(response.return_.empty()) { @@ -723,8 +632,8 @@ namespace Mantid // we just wanted to perform the getSearchQuery to build our COUNT query. if (offset == -1 || limit == -1) return; - std::string ses = Session::Instance().getSessionId(); - request.sessionId = &ses; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; // Setup paging information to search with paging enabled. request.numberOfResults = limit; request.startIndex = offset; @@ -856,8 +765,8 @@ namespace Mantid ns1__searchByAdvanced request; ns1__searchByAdvancedResponse response; - std::string session = Session::Instance().getSessionId(); - request.sessionId = &session; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; request.advancedSearchDetails = buildSearchQuery(inputs); int result = icat.searchByAdvanced(&request, &response); @@ -878,24 +787,6 @@ namespace Mantid return numOfResults; } - /**This method checks the given session is valid - *@return returns true if the session id is valid,otherwise false; - */ - bool CICatHelper::isvalidSession() - { - ICATPortBindingProxy icat; - setICATProxySettings(icat); - - ns1__isSessionValid request; - ns1__isSessionValidResponse response; - std::string sessionId=Session::Instance().getSessionId(); - request.sessionId = &sessionId; - - return (response.return_? true: false); - - - } - /** * Authenticate the user against all catalogues in the container. * @param username :: The login name of the user. @@ -903,12 +794,11 @@ namespace Mantid * @param endpoint :: The endpoint url of the catalog to log in to. * @param facility :: The facility of the catalog to log in to. */ - void CICatHelper::doLogin(const std::string& username,const std::string& password, + API::CatalogSession_sptr CICatHelper::doLogin(const std::string& username,const std::string& password, const std::string& endpoint, const std::string& facility) { - // Store the soap end-point in the session for use later. - ICat::Session::Instance().setSoapEndPoint(endpoint); - + m_session = boost::make_shared("",facility,endpoint); + // Obtain the ICAT proxy that has been securely set, including soap-endpoint. ICATPortBindingProxy icat; setICATProxySettings(icat); @@ -922,25 +812,20 @@ namespace Mantid std::string userName(username); std::string passWord(password); + login.username = &userName; login.password = &passWord; - std::string session_id; - int query_id = icat.login(&login, &loginResponse); if( query_id == 0 ) { - session_id = *(loginResponse.return_); - //save session id - ICat::Session::Instance().setSessionId(session_id); - //save user name - ICat::Session::Instance().setUserName(userName); + m_session->setSessionId(*(loginResponse.return_)); } else { throw std::runtime_error("Username or password supplied is invalid."); } - + return m_session; } const std::string CICatHelper::getdownloadURL(const long long& fileId) @@ -953,13 +838,10 @@ namespace Mantid std::string downloadURL; - boost::shared_ptrsessionId_sptr(new std::string); - request.sessionId = sessionId_sptr.get(); - *request.sessionId = Session::Instance().getSessionId(); - - boost::shared_ptrfileId_sptr(new LONG64 ); - request.datafileId=fileId_sptr.get(); - *request.datafileId= fileId; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + LONG64 fileID = fileId; + request.datafileId = &fileID; // get the URL using ICAT API int ret=icat.downloadDatafile(&request,&response); @@ -984,13 +866,10 @@ namespace Mantid std::string filelocation; - boost::shared_ptrsessionId_sptr(new std::string); - request.sessionId=sessionId_sptr.get(); - *request.sessionId = Session::Instance().getSessionId(); - - boost::shared_ptrfileId_sptr(new LONG64 ); - request.datafileId=fileId_sptr.get(); - *request.datafileId=fileid; + std::string sessionID = m_session->getSessionId(); + request.sessionId = &sessionID; + LONG64 fileID = fileid; + request.datafileId = &fileID; int ret=icat.getDatafile(&request,&response); @@ -1010,7 +889,7 @@ namespace Mantid void CICatHelper::setICATProxySettings(ICat3::ICATPortBindingProxy& icat) { // Set the soap-endpoint of the catalog we want to use. - icat.soap_endpoint = ICat::Session::Instance().getSoapEndPoint().c_str(); + icat.soap_endpoint = m_session->getSoapEndpoint().c_str(); // Sets SSL authentication scheme setSSLContext(icat); } From aa1545f41d87e77de69f181bf62de49c76013abe Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 11:40:30 +0000 Subject: [PATCH 040/118] Removed old singleton session. Refs #9084. - Removed references to session from unit-tests. Th - Updated `CompositeCatalogTest` to throw an runtime on login method. --- Code/Mantid/Framework/ICat/CMakeLists.txt | 1 - .../Framework/ICat/inc/MantidICat/Session.h | 80 ------------------- .../ICat/src/CatalogDownloadDataFiles.cpp | 1 - .../ICat/test/CatalogDownloadDataFilesTest.h | 6 -- .../ICat/test/CatalogGetDataFilesTest.h | 5 -- .../ICat/test/CatalogGetDataSetsTest.h | 5 -- .../ICat/test/CatalogListInstrumentsTest.h | 5 -- .../test/CatalogListInvestigationTypesTest.h | 3 - .../Framework/ICat/test/CatalogLoginTest.h | 8 -- .../ICat/test/CatalogMyDataSearchTest.h | 6 +- .../Framework/ICat/test/CatalogSearchTest.h | 13 ++- .../ICat/test/CompositeCatalogTest.h | 10 +-- .../Framework/ICat/test/ICatTestHelper.h | 1 - 13 files changed, 10 insertions(+), 134 deletions(-) delete mode 100644 Code/Mantid/Framework/ICat/inc/MantidICat/Session.h diff --git a/Code/Mantid/Framework/ICat/CMakeLists.txt b/Code/Mantid/Framework/ICat/CMakeLists.txt index ca86bd3e696a..3fb97570497e 100644 --- a/Code/Mantid/Framework/ICat/CMakeLists.txt +++ b/Code/Mantid/Framework/ICat/CMakeLists.txt @@ -36,7 +36,6 @@ set ( INC_FILES inc/MantidICat/CatalogSearch.h inc/MantidICat/CatalogSearchParam.h inc/MantidICat/ICatExport.h - inc/MantidICat/Session.h inc/MantidICat/GSoap/soapserializersH.h inc/MantidICat/GSoap/soapserializersStub.h inc/MantidICat/GSoap/stdsoap2.h diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/Session.h b/Code/Mantid/Framework/ICat/inc/MantidICat/Session.h deleted file mode 100644 index 6cae0713864a..000000000000 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/Session.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef MANTID_ICAT_SESSION_H_ -#define MANTID_ICAT_SESSION_H_ - -#include "MantidKernel/SingletonHolder.h" -#include "MantidICat/ICatExport.h" - -namespace Mantid -{ - namespace ICat - { - -/** SessionImpl is a singleton class responsible for saving the session id. - This class is used across all Mantid-ICat algorithms to get the session id - - @author Sofia Antony, ISIS Rutherford Appleton Laboratory - @date 07/07/2010 - Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: - */ - class EXPORT_OPT_MANTID_ICAT SessionImpl - { - public: - ///get sessionId - const std::string& getSessionId() const { return m_sessionId; } - /// set session id - void setSessionId(const std::string& sessionId) { m_sessionId=sessionId; } - /// get user name - const std::string & getUserName() const { return m_userName; } - ///set username - void setUserName(const std::string& userName) { m_userName=userName; } - /// Get the soap end-point. - const std::string & getSoapEndPoint() const { return m_soapEndPoint; } - /// Set the soap end-point. - void setSoapEndPoint(const std::string& soapEndPoint) { m_soapEndPoint = soapEndPoint; } - - private: - /// used to create singleton - friend struct Mantid::Kernel::CreateUsingNew; - /// private constructor for singleton - SessionImpl(){} - /// private destructor - virtual ~SessionImpl(){} - ///private copy constructor - SessionImpl(const SessionImpl&); - /// private assignment - SessionImpl operator = (const SessionImpl&); - /// string to cache session id - std::string m_sessionId; - /// user name - std::string m_userName; - /// Cache soap end-point - std::string m_soapEndPoint; - }; - -#ifdef _WIN32 - // this breaks new namespace declaraion rules; need to find a better fix - template class EXPORT_OPT_MANTID_ICAT Mantid::Kernel::SingletonHolder; -#endif /* _WIN32 */ - typedef EXPORT_OPT_MANTID_ICAT Mantid::Kernel::SingletonHolder Session; - } -} - -#endif diff --git a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp index d8bc8c62f1c8..7483a648a098 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp @@ -9,7 +9,6 @@ if the data archive is not accessible, it downloads the files from the data serv #include "MantidAPI/ICatalogInfoService.h" #include "MantidICat/CatalogDownloadDataFiles.h" #include "MantidICat/CatalogAlgorithmHelper.h" -#include "MantidICat/Session.h" #include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ConfigService.h" diff --git a/Code/Mantid/Framework/ICat/test/CatalogDownloadDataFilesTest.h b/Code/Mantid/Framework/ICat/test/CatalogDownloadDataFilesTest.h index 09ae8e3ad469..2710f389091c 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogDownloadDataFilesTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogDownloadDataFilesTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogDownloadDataFiles.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidICat/CatalogGetDataFiles.h" #include "MantidICat/CatalogSearch.h" @@ -61,7 +60,6 @@ class CatalogDownloadDataFilesTest: public CxxTest::TestSuite } void xtestDownLoadDataFile() { - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantidtest@fitsp10.isis.cclrc.ac.uk"); @@ -121,8 +119,6 @@ class CatalogDownloadDataFilesTest: public CxxTest::TestSuite void xtestDownLoadNexusFile() { - Session::Instance(); - if ( !loginobj.isInitialized() ) loginobj.initialize(); // Now set it... @@ -182,8 +178,6 @@ class CatalogDownloadDataFilesTest: public CxxTest::TestSuite void xtestDownLoadDataFile_Merlin() { - - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantidtest@fitsp10.isis.cclrc.ac.uk"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogGetDataFilesTest.h b/Code/Mantid/Framework/ICat/test/CatalogGetDataFilesTest.h index f035d93d1e79..f850b203971a 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogGetDataFilesTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogGetDataFilesTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogGetDataFiles.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidICat/CatalogSearch.h" #include "MantidDataObjects/WorkspaceSingleValue.h" @@ -30,10 +29,6 @@ class CatalogGetDataFilesTest: public CxxTest::TestSuite void testgetDataFiles() { - /*std::string str; - std::getline(std::cin,str);*/ - - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogGetDataSetsTest.h b/Code/Mantid/Framework/ICat/test/CatalogGetDataSetsTest.h index 406c57e3cca6..003707c1e225 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogGetDataSetsTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogGetDataSetsTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogGetDataSets.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidICat/CatalogSearch.h" #include "MantidDataObjects/WorkspaceSingleValue.h" @@ -31,10 +30,6 @@ class CatalogGetDataSetsTest: public CxxTest::TestSuite void testgetDataFiles() { - /*std::string str; - std::getline(std::cin,str);*/ - - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogListInstrumentsTest.h b/Code/Mantid/Framework/ICat/test/CatalogListInstrumentsTest.h index ab9e28462270..167ad21331df 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogListInstrumentsTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogListInstrumentsTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogListInstruments.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidDataObjects/WorkspaceSingleValue.h"// why this is required to register table workspace. #include "ICatTestHelper.h" @@ -30,10 +29,6 @@ class CatalogListInstrumentsTest: public CxxTest::TestSuite void testListInstruments() { - /*std::string s; - std::getline(std::cin,s);*/ - - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogListInvestigationTypesTest.h b/Code/Mantid/Framework/ICat/test/CatalogListInvestigationTypesTest.h index fcf5d6c95a1c..2cbdb1ab07c6 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogListInvestigationTypesTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogListInvestigationTypesTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogListInvestigationTypes.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidDataObjects/WorkspaceSingleValue.h"// why this is required to register table workspace. #include "ICatTestHelper.h" @@ -30,8 +29,6 @@ class CatalogListInvestigationTypesTest: public CxxTest::TestSuite void testListInvestigationTypes() { - - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogLoginTest.h b/Code/Mantid/Framework/ICat/test/CatalogLoginTest.h index 5509024ce437..49a0b68564f0 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogLoginTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogLoginTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogLogin.h" -#include "MantidICat/Session.h" #include "ICatTestHelper.h" using namespace Mantid::ICat; @@ -26,9 +25,6 @@ class CatalogLoginTest: public CxxTest::TestSuite } void testLogin() { - /*std::string s; - std::getline(std::cin,s);*/ - Session::Instance(); CatalogLogin loginobj; if ( !loginobj.isInitialized() ) loginobj.initialize(); @@ -49,7 +45,6 @@ class CatalogLoginTest: public CxxTest::TestSuite { CatalogLogin loginobj; - Session::Instance(); if ( !loginobj.isInitialized() ) loginobj.initialize(); @@ -64,9 +59,6 @@ class CatalogLoginTest: public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING(loginobj.execute()); //should fail TS_ASSERT( !loginobj.isExecuted() ); - //empty sessionid - TS_ASSERT(!Session::Instance().getSessionId().empty()); - } diff --git a/Code/Mantid/Framework/ICat/test/CatalogMyDataSearchTest.h b/Code/Mantid/Framework/ICat/test/CatalogMyDataSearchTest.h index 121224e02dda..4e71b154b041 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogMyDataSearchTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogMyDataSearchTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogMyDataSearch.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidDataObjects/WorkspaceSingleValue.h" #include "ICatTestHelper.h" @@ -30,12 +29,9 @@ class CatalogMyDataSearchTest: public CxxTest::TestSuite } void testMyDataSearch() { - /*std::string s; - std::getline(std::cin,s);*/ - CatalogMyDataSearch mydata; CatalogLogin loginobj; - Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CatalogSearchTest.h b/Code/Mantid/Framework/ICat/test/CatalogSearchTest.h index 0520d475aadb..e66f745667d3 100644 --- a/Code/Mantid/Framework/ICat/test/CatalogSearchTest.h +++ b/Code/Mantid/Framework/ICat/test/CatalogSearchTest.h @@ -3,7 +3,6 @@ #include #include "MantidICat/CatalogSearch.h" -#include "MantidICat/Session.h" #include "MantidICat/CatalogLogin.h" #include "MantidDataObjects/WorkspaceSingleValue.h" #include "MantidAPI/FrameworkManager.h" @@ -39,7 +38,7 @@ class CatalogSearchTest: public CxxTest::TestSuite CatalogSearch searchobj; CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); @@ -65,7 +64,7 @@ class CatalogSearchTest: public CxxTest::TestSuite CatalogSearch searchobj; CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); @@ -89,7 +88,7 @@ class CatalogSearchTest: public CxxTest::TestSuite { CatalogSearch searchobj; CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); @@ -111,7 +110,7 @@ class CatalogSearchTest: public CxxTest::TestSuite void testSearchByRunNumberInvalidInput() { CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); // Now set it... @@ -140,7 +139,7 @@ class CatalogSearchTest: public CxxTest::TestSuite { CatalogSearch searchobj; CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); @@ -164,7 +163,7 @@ class CatalogSearchTest: public CxxTest::TestSuite CatalogSearch searchobj; CatalogLogin loginobj; - ICat::Session::Instance(); + if ( !loginobj.isInitialized() ) loginobj.initialize(); loginobj.setPropertyValue("Username", "mantid_test"); diff --git a/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h b/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h index 0b00035da781..e46eeed6c99d 100644 --- a/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h +++ b/Code/Mantid/Framework/ICat/test/CompositeCatalogTest.h @@ -20,9 +20,9 @@ class DummyCatalog : public ICatalog { public: - void login(const std::string&,const std::string&,const std::string&) + CatalogSession_sptr login(const std::string&,const std::string&,const std::string&,const std::string&) { - m_counter++; + throw std::runtime_error("You cannot log into multiple catalogs at the same time."); } void logout() @@ -95,11 +95,7 @@ class CompositeCatalogTest : public CxxTest::TestSuite void testLogin() { std::string temp = ""; - // This will attempt to login to each dummy catalog - // that has been added to the composite created. - createCompositeCatalog()->login(temp,temp,temp); - // Verify that the composite catalog login method works as expected. - TS_ASSERT_EQUALS(DummyCatalog::m_counter,2); + TS_ASSERT_THROWS(createCompositeCatalog()->login(temp,temp,temp, temp),std::runtime_error&); } void testLogout() diff --git a/Code/Mantid/Framework/ICat/test/ICatTestHelper.h b/Code/Mantid/Framework/ICat/test/ICatTestHelper.h index 6bd415a3fc81..84c8467a2173 100644 --- a/Code/Mantid/Framework/ICat/test/ICatTestHelper.h +++ b/Code/Mantid/Framework/ICat/test/ICatTestHelper.h @@ -2,7 +2,6 @@ #define ICATTESTHELPER_H_ #include "MantidICat/CatalogLogin.h" -#include "MantidICat/Session.h" #include "MantidKernel/ConfigService.h" namespace ICatTestHelper From b9763b2e42a676b9632151a41e9f2fe4bd1d9d49 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 12:15:06 +0000 Subject: [PATCH 041/118] Fix build issue on OSX. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h index 9fc9739791c0..7926cc8ce9e4 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -3,6 +3,7 @@ #include "MantidAPI/DllConfig.h" #include "boost/shared_ptr.hpp" +#include namespace Mantid { From 5e23bb4255eaf87bbdb827633710dbc92e8e6002 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 12:22:10 +0000 Subject: [PATCH 042/118] Attempt to fix OSX build. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h index 7926cc8ce9e4..23087f80f0da 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -3,7 +3,7 @@ #include "MantidAPI/DllConfig.h" #include "boost/shared_ptr.hpp" -#include +#include namespace Mantid { From dfd34a49c3b33e36b9f729aecb13e056698f4b87 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 14:59:06 +0000 Subject: [PATCH 043/118] Prevent column with name exists error. Refs #9084. --- .../Framework/ICat/src/ICat3/ICat3Helper.cpp | 78 +++++++++---------- .../Framework/ICat/src/ICat4/ICat4Catalog.cpp | 52 ++++++++----- 2 files changed, 69 insertions(+), 61 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index b5aa0a033852..2c90674dcf73 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -48,26 +48,18 @@ namespace Mantid */ void CICatHelper::saveSearchRessults(const ns1__searchByAdvancedPaginationResponse& response,API::ITableWorkspace_sptr& outputws) { - //create table workspace - //API::ITableWorkspace_sptr outputws =createTableWorkspace(); - - outputws->addColumn("long64","InvestigationId"); - outputws->addColumn("str","Proposal"); - outputws->addColumn("str","Title"); - outputws->addColumn("str","Instrument"); - outputws->addColumn("str","Run Range"); - - try - { - saveInvestigations(response.return_,outputws); - } - catch(std::runtime_error& ) + if (outputws->getColumnNames().empty()) { - throw std::runtime_error("Error when saving the ICat Search Results data to Workspace"); + outputws->addColumn("long64","InvestigationId"); + outputws->addColumn("str","Proposal"); + outputws->addColumn("str","Title"); + outputws->addColumn("str","Instrument"); + outputws->addColumn("str","Run Range"); } - + saveInvestigations(response.return_,outputws); } + /** This method saves investigations to a table workspace * @param investigations :: a vector containing investigation data * @param outputws :: shared pointer to output workspace @@ -195,12 +187,13 @@ namespace Mantid { //create table workspace API::ITableWorkspace_sptr outputws =createTableWorkspace(); - //add columns - outputws->addColumn("str","Name"); - outputws->addColumn("str","Location"); - outputws->addColumn("str","Create Time"); - outputws->addColumn("long64","Id"); - + if (outputws->getColumnNames().empty()) + { + outputws->addColumn("str","Name"); + outputws->addColumn("str","Location"); + outputws->addColumn("str","Create Time"); + outputws->addColumn("long64","Id"); + } std::vector investVec; investVec.assign(response.return_.begin(),response.return_.end()); @@ -294,11 +287,13 @@ namespace Mantid void CICatHelper::saveInvestigationIncludesResponse(const ns1__getInvestigationIncludesResponse& response, API::ITableWorkspace_sptr& outputws) { - - outputws->addColumn("str","Name"); - outputws->addColumn("str","Location"); - outputws->addColumn("str","Create Time"); - outputws->addColumn("long64","Id"); + if (outputws->getColumnNames().empty()) + { + outputws->addColumn("str","Name"); + outputws->addColumn("str","Location"); + outputws->addColumn("str","Create Time"); + outputws->addColumn("long64","Id"); + } try { std::vector datasetVec; @@ -414,13 +409,14 @@ namespace Mantid void CICatHelper::saveDataSets(const ns1__getInvestigationIncludesResponse& response,API::ITableWorkspace_sptr& outputws) { //create table workspace - //adding columns - outputws->addColumn("str","Name");//File name - outputws->addColumn("str","Status"); - outputws->addColumn("str","Type"); - outputws->addColumn("str","Description"); - outputws->addColumn("long64","Sample Id"); - + if (outputws->getColumnNames().empty()) + { + outputws->addColumn("str","Name");//File name + outputws->addColumn("str","Status"); + outputws->addColumn("str","Type"); + outputws->addColumn("str","Description"); + outputws->addColumn("long64","Sample Id"); + } try { @@ -598,12 +594,14 @@ namespace Mantid */ void CICatHelper::saveMyInvestigations( const ns1__getMyInvestigationsIncludesResponse& response,API::ITableWorkspace_sptr& outputws) { - outputws->addColumn("long64","InvestigationId"); - outputws->addColumn("str","Proposal"); - outputws->addColumn("str","Title"); - outputws->addColumn("str","Instrument"); - outputws->addColumn("str","Run Range"); - + if(outputws->getColumnNames().empty()) + { + outputws->addColumn("long64","InvestigationId"); + outputws->addColumn("str","Proposal"); + outputws->addColumn("str","Title"); + outputws->addColumn("str","Instrument"); + outputws->addColumn("str","Run Range"); + } saveInvestigations(response.return_,outputws); } diff --git a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp index 6f2947e77374..0be0d0769b84 100644 --- a/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat4/ICat4Catalog.cpp @@ -375,13 +375,16 @@ namespace Mantid */ void ICat4Catalog::saveInvestigations(std::vector response, API::ITableWorkspace_sptr& outputws) { - // Add rows headers to the output workspace. - outputws->addColumn("str","Investigation id"); - outputws->addColumn("str","Title"); - outputws->addColumn("str","Instrument"); - outputws->addColumn("str","Run range"); - outputws->addColumn("str","Start date"); - outputws->addColumn("str","End date"); + if (outputws->getColumnNames().empty()) + { + // Add rows headers to the output workspace. + outputws->addColumn("str","Investigation id"); + outputws->addColumn("str","Title"); + outputws->addColumn("str","Instrument"); + outputws->addColumn("str","Run range"); + outputws->addColumn("str","Start date"); + outputws->addColumn("str","End date"); + } // Add data to each row in the output workspace. std::vector::const_iterator iter; @@ -475,12 +478,16 @@ namespace Mantid */ void ICat4Catalog::saveDataSets(std::vector response, API::ITableWorkspace_sptr& outputws) { - // Add rows headers to the output workspace. - outputws->addColumn("str","Name"); - outputws->addColumn("str","Status"); - outputws->addColumn("str","Type"); - outputws->addColumn("str","Description"); - outputws->addColumn("str","Sample Id"); + if (outputws->getColumnNames().empty()) + { + // Add rows headers to the output workspace. + outputws->addColumn("str","Name"); + outputws->addColumn("str","Status"); + outputws->addColumn("str","Type"); + outputws->addColumn("str","Description"); + outputws->addColumn("str","Sample Id"); + } + std::string temp(""); std::vector::const_iterator iter; @@ -537,14 +544,17 @@ namespace Mantid */ void ICat4Catalog::saveDataFiles(std::vector response, API::ITableWorkspace_sptr& outputws) { - // Add rows headers to the output workspace. - outputws->addColumn("str","Name"); - outputws->addColumn("str","Location"); - outputws->addColumn("str","Create Time"); - outputws->addColumn("long64","Id"); - outputws->addColumn("long64","File size(bytes)"); - outputws->addColumn("str","File size"); - outputws->addColumn("str","Description"); + if (outputws->getColumnNames().empty()) + { + // Add rows headers to the output workspace. + outputws->addColumn("str","Name"); + outputws->addColumn("str","Location"); + outputws->addColumn("str","Create Time"); + outputws->addColumn("long64","Id"); + outputws->addColumn("long64","File size(bytes)"); + outputws->addColumn("str","File size"); + outputws->addColumn("str","Description"); + } std::vector::const_iterator iter; for(iter = response.begin(); iter != response.end(); ++iter) From 4b3d3456920b42803817b188657c697d3ce2b53f Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 15:04:08 +0000 Subject: [PATCH 044/118] Removed unused methods from ICat3Helper. Refs #9084. --- .../ICat/inc/MantidICat/ICat3/ICat3Helper.h | 12 -- .../Framework/ICat/src/ICat3/ICat3Helper.cpp | 195 ------------------ 2 files changed, 207 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h index de4195c24c70..3810eed12268 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h @@ -86,9 +86,6 @@ namespace Mantid private: - ///This method saves the file search response to table workspace - API::ITableWorkspace_sptr saveFileSearchResponse(const ICat3::ns1__searchByAdvancedResponse& response); - /// This method saves the response data of search by run number to table workspace void saveSearchRessults(const ICat3::ns1__searchByAdvancedPaginationResponse& response,API::ITableWorkspace_sptr& outputws); @@ -100,21 +97,12 @@ namespace Mantid /// This method saves Datasets to a table workspace void saveDataSets(const ICat3::ns1__getInvestigationIncludesResponse& response,API::ITableWorkspace_sptr& outputws); - /// This method creates table workspace - API::ITableWorkspace_sptr createTableWorkspace(); - - /// This method checks the given file name is raw file or nexus file - bool isDataFile(const std::string* fileName); - /// This method saves the myinvestigations data to a table workspace void saveMyInvestigations(const ICat3::ns1__getMyInvestigationsIncludesResponse& response,API::ITableWorkspace_sptr& outputws); ///save investigations void saveInvestigations(const std::vector& investigations,API::ITableWorkspace_sptr& outputws); - ///saves - void saveInvestigatorsNameandSample(ICat3::ns1__investigation* investigation,API::TableRow& t); - /// Builds search query based on user input and stores query in related ICAT class. ICat3::ns1__advancedSearchDetails* buildSearchQuery(const CatalogSearchParam& inputs); diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index 2c90674dcf73..704c9fd36e48 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -48,7 +48,6 @@ namespace Mantid */ void CICatHelper::saveSearchRessults(const ns1__searchByAdvancedPaginationResponse& response,API::ITableWorkspace_sptr& outputws) { - //API::ITableWorkspace_sptr outputws =createTableWorkspace(); if (outputws->getColumnNames().empty()) { outputws->addColumn("long64","InvestigationId"); @@ -96,156 +95,6 @@ namespace Mantid } } - /** This method saves investigations to a table workspace - * @param investigation :: pointer to a single investigation data - * @param t :: reference to a row in a table workspace - */ - void CICatHelper::saveInvestigatorsNameandSample(ns1__investigation* investigation,API::TableRow& t) - { - - try - { - - // abstract - savetoTableWorkspace(investigation->invAbstract,t); - - std::vectorinvestigators; - investigators.assign(investigation->investigatorCollection.begin(),investigation->investigatorCollection.end()); - - std::string fullname; std::string* facilityUser=NULL; - //for loop for getting invetigator's first and last name - std::vector::const_iterator invstrItr; - for(invstrItr=investigators.begin();invstrItr!=investigators.end();++invstrItr) - { - std::string firstname;std::string lastname;std::string name; - if((*invstrItr)->ns1__facilityUser_) - { - - if((*invstrItr)->ns1__facilityUser_->firstName) - { - firstname = *(*invstrItr)->ns1__facilityUser_->firstName; - } - if((*invstrItr)->ns1__facilityUser_->lastName) - { - lastname = *(*invstrItr)->ns1__facilityUser_->lastName; - } - name = firstname+" "+ lastname; - } - if(!fullname.empty()) - { - fullname+=","; - } - fullname+=name; - }//end of for loop for investigator's name. - - if(!fullname.empty()) - { - facilityUser = new std::string; - facilityUser->assign(fullname); - } - - //invetigator name - savetoTableWorkspace(facilityUser,t); - - std::vectorsamples; - std::string *samplenames =NULL; - samples.assign(investigation->sampleCollection.begin(),investigation->sampleCollection.end()); - std::string sNames; - //for loop for samples name. - std::vector::const_iterator sItr; - for(sItr=samples.begin();sItr!=samples.end();++sItr) - { - std::string sName; - if((*sItr)->name) - { - sName=*((*sItr)->name); - } - if(!sNames.empty()) - { - sNames+=","; - } - sNames+=sName; - } - if(!sNames.empty()) - { - samplenames = new std::string; - samplenames->assign(sNames); - } - savetoTableWorkspace(samplenames,t); - } - catch(std::runtime_error& ) - { - throw std::runtime_error("Error when saving the ICat Search Results data to Workspace"); - } - } - - /** This method loops through the response return_vector and saves the datafile details to a table workspace - * @param response :: const reference to response object - * @returns shared pointer to table workspace which stores the data - */ - API::ITableWorkspace_sptr CICatHelper::saveFileSearchResponse(const ns1__searchByAdvancedResponse& response) - { - //create table workspace - API::ITableWorkspace_sptr outputws =createTableWorkspace(); - if (outputws->getColumnNames().empty()) - { - outputws->addColumn("str","Name"); - outputws->addColumn("str","Location"); - outputws->addColumn("str","Create Time"); - outputws->addColumn("long64","Id"); - } - std::vector investVec; - investVec.assign(response.return_.begin(),response.return_.end()); - - try - { - std::vector::const_iterator inv_citr; - for (inv_citr=investVec.begin();inv_citr!=investVec.end();++inv_citr) - { - std::vector datasetVec; - datasetVec.assign((*inv_citr)->datasetCollection.begin(),(*inv_citr)->datasetCollection.end()); - - std::vector::const_iterator dataset_citr; - for(dataset_citr=datasetVec.begin();dataset_citr!=datasetVec.end();++dataset_citr) - { - std::vectordatafileVec; - datafileVec.assign((*dataset_citr)->datafileCollection.begin(),(*dataset_citr)->datafileCollection.end()); - - std::vector::const_iterator datafile_citr; - for(datafile_citr=datafileVec.begin();datafile_citr!=datafileVec.end();++datafile_citr) - { - - API::TableRow t = outputws->appendRow(); - savetoTableWorkspace((*datafile_citr)->name,t); - savetoTableWorkspace((*datafile_citr)->location,t); - - if((*datafile_citr)->datafileCreateTime!=NULL) - { - time_t crtime=*(*datafile_citr)->datafileCreateTime; - char temp [25]; - strftime (temp,25,"%Y-%b-%d %H:%M:%S",localtime(&crtime)); - std::string ftime(temp); - std::string *creationtime=new std::string ; - creationtime->assign(ftime); - savetoTableWorkspace(creationtime,t); - savetoTableWorkspace((*datafile_citr)->id,t); - } - - }//end of for loop for data files iteration - - }//end of for loop for datasets iteration - - - }// end of for loop investigations iteration. - } - catch(std::runtime_error& ) - { - throw; - } - - return outputws; - } - /** * This method calls ICat API getInvestigationIncludes and returns investigation details for a given investigation Id * @param invstId :: investigation id @@ -349,26 +198,6 @@ namespace Mantid } - /**This checks the datafile boolean selected - * @param fileName :: pointer to file name - * @return bool - returns true if it's a raw file or nexus file - */ - - bool CICatHelper::isDataFile(const std::string* fileName) - { - if(!fileName) - { - return false; - } - std::basic_string ::size_type dotIndex; - //find the position of '.' in raw/nexus file name - dotIndex = (*fileName).find_last_of ("."); - std::string fextn=(*fileName).substr(dotIndex+1,(*fileName).size()-dotIndex); - std::transform(fextn.begin(),fextn.end(),fextn.begin(),tolower); - - return((!fextn.compare("raw")|| !fextn.compare("nxs")) ? true : false); - } - /**This method calls ICat API getInvestigationIncludes and returns datasets details for a given investigation Id * @param invstId :: investigation id * @param include :: enum parameter for selecting the response data from iact db. @@ -509,30 +338,6 @@ namespace Mantid } } - - /** This method creates table workspace - * @returns the table workspace created - */ - API::ITableWorkspace_sptr CICatHelper::createTableWorkspace() - { - //create table workspace - API::ITableWorkspace_sptr outputws ; - try - { - outputws=WorkspaceFactory::Instance().createTable("TableWorkspace"); - } - catch(Mantid::Kernel::Exception::NotFoundError& ) - { - throw std::runtime_error("Error when saving the ICat Search Results data to Workspace"); - } - catch(std::runtime_error &) - { - throw std::runtime_error("Error when saving the ICat Search Results data to Workspace"); - } - return outputws; - } - - /** *This method calls ICat api logout and disconnects from ICat DB * @returns zero if successful otherwise error code From 437a561e0c582cd271f10821ab55c09644bf672f Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Fri, 28 Feb 2014 15:29:02 +0000 Subject: [PATCH 045/118] Refs #9056. Return the behaviour changed in #8774. If tables are not cleared before filling, we get problems. --- Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp index 355bf40b8084..958276fda9f9 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp @@ -98,6 +98,9 @@ void MantidTable::fillTable() // temporarily allow resizing d_table->blockResizing(false); + setNumRows(0); + setNumCols(0); + // Resize to fit the new workspace setNumRows(static_cast(m_ws->rowCount())); setNumCols(static_cast(m_ws->columnCount())); From 6017db14bebcec8cec923d825b782a2086225be4 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Fri, 28 Feb 2014 15:31:23 +0000 Subject: [PATCH 046/118] Refs #9056. Move column type setting to fill function. Otherwise column types are set on creating the table and not on when it gets updated. --- .../MantidPlot/src/Mantid/MantidTable.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp index 958276fda9f9..c058c80d2d24 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp @@ -32,14 +32,6 @@ m_wsName(ws->getName()), m_transposed(transpose) { d_table->blockResizing(true); - // if plot types is set in ws then update Table with that information - for ( size_t i = 0; i < ws->columnCount(); i++ ) - { - int pt = ws->getColumn(i)->getPlotType(); - if ( pt != -1000 ) - setColPlotDesignation(static_cast(i), pt); - } - setHeaderColType(); // Filling can take a while, so process any pending events and set appropriate cursor QApplication::processEvents(); @@ -113,6 +105,15 @@ void MantidTable::fillTable() setColName(i,colName); // Make columns of ITableWorkspaces read only, if specified setReadOnlyColumn(i, c->getReadOnly() ); + + // if plot types is set in ws then update Table with that information + int pt = m_ws->getColumn(i)->getPlotType(); + + if ( pt != -1000 ) + { + setColPlotDesignation(static_cast(i), pt); + } + // Special for errors? if (colName.endsWith("_err",Qt::CaseInsensitive) || colName.endsWith("_error",Qt::CaseInsensitive)) @@ -120,6 +121,8 @@ void MantidTable::fillTable() setColPlotDesignation(i,Table::yErr); } + setHeaderColType(); + // Track the column width. All text should fit in. int maxWidth = 60; QFontMetrics fm( this->getTextFont() ); From da0bd4172ada643eff88b97e6d4ae1fdfa32f933 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Fri, 28 Feb 2014 15:35:49 +0000 Subject: [PATCH 047/118] Refs #9056. Minor style improvements. --- Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp index c058c80d2d24..5bd330d88c0e 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidTable.cpp @@ -106,12 +106,12 @@ void MantidTable::fillTable() // Make columns of ITableWorkspaces read only, if specified setReadOnlyColumn(i, c->getReadOnly() ); - // if plot types is set in ws then update Table with that information - int pt = m_ws->getColumn(i)->getPlotType(); + // If plot type is set in ws then update Table with that information + int plotType = m_ws->getColumn(i)->getPlotType(); - if ( pt != -1000 ) + if ( plotType != -1000 ) { - setColPlotDesignation(static_cast(i), pt); + setColPlotDesignation(i, plotType); } // Special for errors? From 0d537f9e02315cfbd2c11bd0c56f49d1d8191dc3 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 15:35:59 +0000 Subject: [PATCH 048/118] Update catalogManger to use catalogSession. Refs #9084. --- .../API/inc/MantidAPI/CatalogManager.h | 2 +- .../Framework/API/src/CatalogManager.cpp | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index 2c1fac0c04a1..e58a86ef606b 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -54,7 +54,7 @@ namespace Mantid virtual ~CatalogManagerImpl(); // Holds a list of active catalogs and uses their sessionId as unique identifier. - std::map m_activeCatalogs; + std::map m_activeCatalogs; }; #ifdef _WIN32 diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index 2b23121bd7d1..b9ac78b274e8 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -42,10 +42,13 @@ namespace Mantid return composite; } - auto pos = m_activeCatalogs.find(sessionID); - // If the key element exists in the map we want the related catalog. - if (pos != m_activeCatalogs.end()) return pos->second; - else throw std::runtime_error("The session ID you have provided is invalid"); + for(auto iter = m_activeCatalogs.begin(); iter != m_activeCatalogs.end(); ++iter) + { + if (sessionID == iter->first->getSessionId()) return iter->second; + } + + // If we reached this point then the session is corrupt/invalid. + throw std::runtime_error("The session ID you have provided is invalid"); } /** @@ -54,12 +57,13 @@ namespace Mantid */ void CatalogManagerImpl::destroyCatalog(const std::string& sessionID) { - auto pos = m_activeCatalogs.find(sessionID); - - if (pos != m_activeCatalogs.end()) + for(auto iter = m_activeCatalogs.begin(); iter != m_activeCatalogs.end(); ++iter) { - pos->second->logout(); - m_activeCatalogs.erase(pos); + if (sessionID == iter->first->getSessionId()) + { + iter->second->logout(); + m_activeCatalogs.erase(iter); + } } } @@ -68,11 +72,10 @@ namespace Mantid */ void CatalogManagerImpl::destroyCatalogs() { - for (auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) + for(auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) { item->second->logout(); } - m_activeCatalogs.clear(); } From 52e4089820dec94cc3ce124b440d9553a2d36cd6 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Fri, 28 Feb 2014 15:37:09 +0000 Subject: [PATCH 049/118] Replace create method with login. Refs #9084. - This allows us to obtain and store the session once the user logs into a catalog. --- .../API/inc/MantidAPI/CatalogManager.h | 5 +++-- .../Framework/API/src/CatalogManager.cpp | 21 ++++++++++++------- .../Framework/ICat/src/CatalogLogin.cpp | 7 ++++--- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index e58a86ef606b..2f828740f671 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -36,8 +36,9 @@ namespace Mantid class MANTID_API_DLL CatalogManagerImpl { public: - /// Create a new catalog, and add it to the list of active catalogs. - ICatalog_sptr create(const std::string &facilityName); + /// Creates a new catalog and session, and adds it to the activeCatalogs container. + CatalogSession_sptr login(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility); /// Get a specific catalog using the sessionID. ICatalog_sptr getCatalog(const std::string &sessionID); /// Destroy and remove a specific catalog from the active catalogs list. diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index b9ac78b274e8..1dc3a498467b 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -13,16 +13,23 @@ namespace Mantid CatalogManagerImpl::~CatalogManagerImpl(){} /** - * Creates a new catalog and adds it to the compositeCatalog and activeCatalog list. - * @param facilityName :: The name of the facility to obtain the catalog name from. - * @return A catalog for the facility specified. + * Logs the user into the catalog if session details are valid. + * This is used here as we need to obtain the session for a specific catalog (e.g. the one created on login). + * @param username :: The login name of the user. + * @param password :: The password of the user. + * @param endpoint :: The endpoint url of the catalog to log in to. + * @param facility :: The facility of the catalog to log in to. + * @return The session created if login was successful. */ - ICatalog_sptr CatalogManagerImpl::create(const std::string &facilityName) + CatalogSession_sptr CatalogManagerImpl::login(const std::string& username,const std::string& password, + const std::string& endpoint,const std::string& facility) { - std::string className = Kernel::ConfigService::Instance().getFacility(facilityName).catalogInfo().catalogName(); + std::string className = Kernel::ConfigService::Instance().getFacility(facility).catalogInfo().catalogName(); auto catalog = CatalogFactory::Instance().create(className); - m_activeCatalogs.insert(std::make_pair(boost::lexical_cast(rand() + 10),catalog)); - return catalog; + CatalogSession_sptr session = catalog->login(username,password,endpoint,facility); + // Creates a new catalog and adds it to the compositeCatalog and activeCatalog list. + m_activeCatalogs.insert(std::make_pair(session,catalog)); + return session; } /** diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp index 12e6994cbb02..31bacdbacb82 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogin.cpp @@ -44,9 +44,10 @@ namespace Mantid if (catalogInfo.soapEndPoint().empty()) throw std::runtime_error("There is no soap end-point for the facility you have selected."); g_log.notice() << "Attempting to verify user credentials against " << catalogInfo.catalogName() << std::endl; progress(0.5, "Verifying user credentials..."); - std::string facility = getProperty("FacilityName"); - auto catalogManager = API::CatalogManager::Instance().create(facility); - catalogManager->login(getProperty("Username"), getProperty("Password"), catalogInfo.soapEndPoint(),facility); + // Creates a new catalog and related session if the authentication is a success. + // This allows us to easily manage sessions alongside catalogs in the catalogmanager. + API::CatalogManager::Instance().login(getProperty("Username"), getProperty("Password"), + catalogInfo.soapEndPoint(),getProperty("FacilityName")); } } From 3519ca9804cd87479d0c20be1399958cd99d884b Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Fri, 28 Feb 2014 17:49:29 +0000 Subject: [PATCH 050/118] Refs #9058. Create layout for every curve, not just once. Otherwise the color and symbol type are set only once and are the same for all the curves. --- Code/Mantid/MantidPlot/src/Graph.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/Graph.cpp b/Code/Mantid/MantidPlot/src/Graph.cpp index ab5104f51064..ee14b462a104 100644 --- a/Code/Mantid/MantidPlot/src/Graph.cpp +++ b/Code/Mantid/MantidPlot/src/Graph.cpp @@ -3193,11 +3193,6 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid } } - // Layout we will use to draw curves - CurveLayout cl = initCurveLayout(style, drawableNames.count() - noOfErrorCols); - cl.sSize = sSize; - cl.lWidth = float(lWidth); - for (int i = 0; i < drawableNames.count(); i++){ QString colName = drawableNames[i]; int colIndex = w->colIndex(colName); @@ -3222,6 +3217,8 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid if (xColName.isEmpty() || yColName.isEmpty()) return false; + PlotCurve* c(NULL); + // --- Drawing error columns ----------------------------- if (colType == Table::xErr || colType == Table::yErr){ int dir; @@ -3230,8 +3227,7 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid else dir = QwtErrorPlotCurve::Vertical; - PlotCurve* c = addErrorBars(xColName, yColName, w, colName, dir); - updateCurveLayout(c, &cl); + c = addErrorBars(xColName, yColName, w, colName, dir); // --- Drawing label columns ----------------------------- } else if (colType == Table::Label){ DataCurve* mc = masterCurve(xColName, yColName); @@ -3243,7 +3239,16 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid // --- Drawing Y columns ----------------------------- } else if (colType == Table::Y) { - PlotCurve* c = insertCurve(w, xColName, yColName, style, startRow, endRow); + c = insertCurve(w, xColName, yColName, style, startRow, endRow); + } + + // Set a layout for the new curve, if we've added one + if (c) + { + CurveLayout cl = initCurveLayout(style, drawableNames.count() - noOfErrorCols); + cl.sSize = sSize; + cl.lWidth = static_cast(lWidth); + updateCurveLayout(c, &cl); } } From c9fe52a6a66b49e3b05f771223bc3a5984ccda5a Mon Sep 17 00:00:00 2001 From: Andrei Savici Date: Fri, 28 Feb 2014 16:42:05 -0500 Subject: [PATCH 051/118] Add option to keep some logs in RemoveLogs. Refs #9106 --- .../Framework/DataHandling/src/RemoveLogs.cpp | 14 ++++++-- .../DataHandling/test/RemoveLogsTest.h | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/RemoveLogs.cpp b/Code/Mantid/Framework/DataHandling/src/RemoveLogs.cpp index d9df8a1539f3..2a58e6859342 100644 --- a/Code/Mantid/Framework/DataHandling/src/RemoveLogs.cpp +++ b/Code/Mantid/Framework/DataHandling/src/RemoveLogs.cpp @@ -1,7 +1,7 @@ /*WIKI* -===Removes all logs from workspace=== +Removes all logs from workspace, except those that are specified @@ -27,6 +27,7 @@ #include // used to get ifstream #include +#include namespace Mantid { @@ -39,7 +40,7 @@ DECLARE_ALGORITHM(RemoveLogs) /// Sets documentation strings for this algorithm void RemoveLogs::initDocs() { - this->setWikiSummary("Remove log file(s) from a [[workspace]]. "); + this->setWikiSummary("Remove logs from a [[workspace]]. "); this->setOptionalMessage("Remove logs from a workspace."); } @@ -60,6 +61,8 @@ void RemoveLogs::init() declareProperty( new WorkspaceProperty("Workspace","Anonymous",Direction::InOut), "The name of the workspace to which the log data will be removed"); + declareProperty(new ArrayProperty("KeepLogs",Direction::Input), + "List(comma separated) of logs to be kept"); } @@ -75,6 +78,7 @@ void RemoveLogs::exec() // the log file(s) will be loaded into the run object of the workspace const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace"); const std::vector< Mantid::Kernel::Property * > & logData = localWorkspace->run().getLogData(); + std::vector keepLogs=getProperty("KeepLogs"); std::vector< std::string> logNames; auto pEnd = logData.end(); for(auto pItr = logData.begin(); @@ -84,7 +88,11 @@ void RemoveLogs::exec() } for (std::vector::const_iterator it = logNames.begin(); it != logNames.end(); ++it) { - localWorkspace->mutableRun().removeLogData(*it); + auto location=std::find(keepLogs.begin(), keepLogs.end(), (*it)); + if (location==keepLogs.end()) + { + localWorkspace->mutableRun().removeLogData(*it); + } } // operation was a success and ended normally diff --git a/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h b/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h index fd43cb1bd6b0..5f2058191bfe 100644 --- a/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h +++ b/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h @@ -5,6 +5,7 @@ #include "MantidDataHandling/RemoveLogs.h" #include "MantidDataHandling/LoadLog.h" +#include "MantidDataHandling/LoadNexusLogs.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidGeometry/Instrument.h" #include "MantidDataObjects/Workspace2D.h" @@ -172,6 +173,39 @@ class RemoveLogsTest : public CxxTest::TestSuite do_test_SNSTextFile("Temp1,Temp2,Temp3,Yadda", "C,K,F,Fortnights", false, false); } + void test_KeepLogs() + { + // Create an empty workspace and put it in the AnalysisDataService + Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",1,1,1); + outputSpace = "PartiallyRemoveLogs"; + TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(outputSpace, ws)); + + LoadNexusLogs lnl; + if ( !lnl.isInitialized() ) lnl.initialize(); + + TS_ASSERT_THROWS_NOTHING(lnl.setPropertyValue("Filename", "CNCS_7860") ); + TS_ASSERT_THROWS_NOTHING(lnl.setPropertyValue("Workspace",outputSpace) ); + TS_ASSERT_THROWS_NOTHING(lnl.execute()); + TS_ASSERT( lnl.isExecuted() ); + + // Get back the saved workspace + MatrixWorkspace_sptr output; + TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieveWS(outputSpace)); + + if ( !remover.isInitialized() ) remover.initialize(); + TS_ASSERT_THROWS_NOTHING(remover.setPropertyValue("Workspace", outputSpace)); + TS_ASSERT_THROWS_NOTHING(remover.setPropertyValue("KeepLogs", "Speed5, gd_prtn_chrg")); + TS_ASSERT_THROWS_NOTHING(remover.execute()); + + + TS_ASSERT( remover.isExecuted() ); + + // log should have been removed + TS_ASSERT_THROWS( output->run().getLogData("Speed4"), std::runtime_error); + TS_ASSERT_THROWS_NOTHING( output->run().getLogData("Speed5")); + TS_ASSERT_THROWS_NOTHING( output->run().getLogData("gd_prtn_chrg")); + AnalysisDataService::Instance().remove(outputSpace); + } private: LoadLog loader; From 817e8a585c273a2349df46e0eec3dea12afed015 Mon Sep 17 00:00:00 2001 From: Vickie Lynch Date: Sat, 1 Mar 2014 18:42:47 -0500 Subject: [PATCH 052/118] Refs #9108 add sample positions to attributes --- .../inc/MantidCrystal/SCDPanelErrors.h | 3 +- .../Framework/Crystal/src/SCDPanelErrors.cpp | 29 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h index e190f856d32b..3435ff012f0e 100644 --- a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h @@ -166,11 +166,12 @@ class DLLExport SCDPanelErrors : public API::ParamFunction, public API::IFuncti double a,b,c,alpha,beta,gamma; int NGroups; bool RotateCenters, SampleOffsets; + double SampleX, SampleY, SampleZ; std::string PeakName;//< SCDPanelErrors{PeakName} is name in the Analysis Data Service where the PeaksWorkspace is stored bool a_set,b_set,c_set,alpha_set,beta_set,gamma_set,PeakName_set, BankNames_set, - startX_set,endX_set, NGroups_set; + startX_set,endX_set, NGroups_set, sampleX_set, sampleY_set, sampleZ_set; /** * 0 - no action diff --git a/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp b/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp index 498501069ada..2f6e1740ff6d 100644 --- a/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp +++ b/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp @@ -118,6 +118,9 @@ const string X_END("endX"); const string PEAKS_WKSP("PeakWorkspaceName"); const string ROTATE_CEN("RotateCenters"); const string SAMPLE_OFF("SampleOffsets"); +const string SAMPLE_X("SampleX"); +const string SAMPLE_Y("SampleY"); +const string SAMPLE_Z("SampleZ"); } void initializeAttributeList(vector &attrs) @@ -136,6 +139,9 @@ void initializeAttributeList(vector &attrs) attrs.push_back(NUM_GROUPS); attrs.push_back(ROTATE_CEN); attrs.push_back(SAMPLE_OFF); + attrs.push_back(SAMPLE_X); + attrs.push_back(SAMPLE_Y); + attrs.push_back(SAMPLE_Z); } SCDPanelErrors::SCDPanelErrors() : @@ -147,7 +153,7 @@ SCDPanelErrors::SCDPanelErrors() : initializeAttributeList(m_attrNames); a_set = b_set = c_set = alpha_set = beta_set = gamma_set = PeakName_set = BankNames_set = endX_set - = startX_set = NGroups_set = false; + = startX_set = NGroups_set = sampleX_set = sampleY_set = sampleZ_set = false; // g_log.setLevel(7); @@ -219,6 +225,12 @@ IFunction::Attribute SCDPanelErrors::getAttribute(const std::string &attName) co return Attribute(static_cast(m_startX)); else if (attName == X_END) return Attribute(static_cast(m_endX)); + else if (attName == SAMPLE_X) + return Attribute(SampleX); + else if (attName == SAMPLE_Y) + return Attribute(SampleY); + else if (attName == SAMPLE_Z) + return Attribute(SampleZ); throw std::invalid_argument("Not a valid attribute name \"" + attName + "\""); @@ -1451,6 +1463,21 @@ void SCDPanelErrors::setAttribute(const std::string &attName, const Attribute & SampOffsetDeclareStatus =2; } } + else if (attName == SAMPLE_X) + { + SampleX = value.asDouble(); + sampleX_set = true; + } + else if (attName == SAMPLE_Y) + { + SampleY = value.asDouble(); + sampleY_set = true; + } + else if (attName == SAMPLE_Z) + { + SampleZ = value.asDouble(); + sampleZ_set = true; + } else if (attName == X_START) { m_startX = value.asInt(); From 9cecd2c99618d5366e82305edd9a9576416798f3 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 10 Feb 2014 17:31:47 +0000 Subject: [PATCH 053/118] Checkpoint workspace iterator removal. Refs #8983 --- .../API/inc/MantidAPI/MatrixWorkspace.h | 10 +- .../Framework/API/src/MatrixWorkspace.cpp | 6 - .../Algorithms/src/CorrectToFile.cpp | 120 ++++++++++-------- Code/Mantid/Framework/Algorithms/src/Qxy.cpp | 12 +- .../inc/MantidDataObjects/RebinnedOutput.h | 4 - .../inc/MantidDataObjects/Workspace2D.h | 4 - .../MantidDataObjects/WorkspaceSingleValue.h | 4 - .../DataObjects/src/EventWorkspace.cpp | 6 - 8 files changed, 76 insertions(+), 90 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h index b99e24e874af..7183da5e5f71 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -4,17 +4,17 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include #include "MantidAPI/DllConfig.h" +#include "MantidAPI/Axis.h" #include "MantidAPI/ExperimentInfo.h" #include "MantidAPI/IMDWorkspace.h" -#include "MantidAPI/Axis.h" #include "MantidAPI/ISpectrum.h" #include "MantidAPI/MatrixWSIndexCalculator.h" #include "MantidAPI/Run.h" #include "MantidAPI/Sample.h" #include "MantidAPI/SpectraDetectorTypes.h" -#include "MantidAPI/WorkspaceIterator.h" + +#include namespace Mantid { @@ -68,10 +68,6 @@ namespace Mantid // The Workspace Factory create-from-parent method needs direct access to the axes. friend class WorkspaceFactoryImpl; - /// Typedef for the workspace_iterator to use with a Workspace - typedef workspace_iterator iterator; - /// Typedef for the const workspace_iterator to use with a Workspace - typedef workspace_iterator const_iterator; /// Initialize void initialize(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength); /// Delete diff --git a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp index 69856a537b80..e05545273ced 100644 --- a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp +++ b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp @@ -3,7 +3,6 @@ #include "MantidAPI/SpectraAxis.h" #include "MantidAPI/MatrixWorkspaceMDIterator.h" #include "MantidAPI/SpectrumDetectorMapping.h" -#include "MantidAPI/WorkspaceIteratorCode.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidGeometry/Instrument/NearestNeighboursFactory.h" @@ -1630,11 +1629,6 @@ namespace Mantid } // namespace API } // Namespace Mantid - -///\cond TEMPLATE -template MANTID_API_DLL class Mantid::API::workspace_iterator; -template MANTID_API_DLL class Mantid::API::workspace_iterator; - namespace Mantid { namespace Kernel diff --git a/Code/Mantid/Framework/Algorithms/src/CorrectToFile.cpp b/Code/Mantid/Framework/Algorithms/src/CorrectToFile.cpp index 56b4bd2b6254..410ca89edcdf 100644 --- a/Code/Mantid/Framework/Algorithms/src/CorrectToFile.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CorrectToFile.cpp @@ -90,69 +90,77 @@ void CorrectToFile::exec() const bool divide = (operation == "Divide") ? true : false; double Yfactor,correctError; - const size_t nOutSpec = outputWS->getNumberHistograms(); + const int64_t nOutSpec = static_cast(outputWS->getNumberHistograms()); + const size_t nbins = outputWS->blocksize(); // Set the progress bar Progress prg(this,0/*LOAD_TIME*/,1.0, nOutSpec); - MatrixWorkspace::iterator outIt(*outputWS); - for (MatrixWorkspace::const_iterator inIt(*toCorrect); inIt != inIt.end(); ++inIt,++outIt) + for(int64_t i = 0; i < nOutSpec; ++i) { - const double currentX = histogramData ? (inIt->X()+inIt->X2())/2.0 : inIt->X(); - // Find out the index of the first correction point after this value - MantidVec::const_iterator pos = std::lower_bound(Xcor.begin(),Xcor.end(),currentX); - const size_t index = pos-Xcor.begin(); - if ( index == Xcor.size() ) - { - // If we're past the end of the correction factors vector, use the last point - Yfactor = Ycor[index-1]; - correctError = Ecor[index-1]; - } - else if (index) - { - // Calculate where between the two closest points our current X value is - const double fraction = (currentX-Xcor[index-1])/(Xcor[index]-Xcor[index-1]); - // Now linearly interpolate to find the correction factors to use - Yfactor = Ycor[index-1] + fraction*(Ycor[index]-Ycor[index-1]); - correctError = Ecor[index-1] + fraction*(Ecor[index]-Ecor[index-1]); - } - else - { - // If we're before the start of the correction factors vector, use the first point - Yfactor = Ycor[0]; - correctError = Ecor[0]; - } + MantidVec & xOut = outputWS->dataX(i); + MantidVec & yOut = outputWS->dataY(i); + MantidVec & eOut = outputWS->dataE(i); - // Now do the correction on the current point - if (divide) - { - outIt->Y() = inIt->Y()/Yfactor; - // the proportional error is equal to the sum of the proportional errors - // re-arrange so that you don't get infinity if leftY==0. Sa = error on a, etc. - // c = a/b - // (Sa/a)2 + (Sb/b)2 = (Sc/c)2 - // (Sa c/a)2 + (Sb c/b)2 = (Sc)2 - // = (Sa 1/b)2 + (Sb (a/b2))2 - // (Sc)2 = (1/b)2( (Sa)2 + (Sb a/b)2 ) - outIt->E() = sqrt( pow(inIt->E(), 2) + - pow( inIt->Y()*correctError/Yfactor, 2) )/Yfactor; - } - else + const MantidVec & xIn = toCorrect->readX(i); + const MantidVec & yIn = toCorrect->readY(i); + const MantidVec & eIn = toCorrect->readE(i); + + for(size_t j = 0; j < nbins; ++j) { - outIt->Y() = inIt->Y()*Yfactor; - // error multiplying two uncorrelated numbers, re-arrange so that you don't get infinity if leftY or rightY == 0 - // Sa = error on a, etc. - // c = a*b - // (Sa/a)2 + (Sb/b)2 = (Sc/c)2 - // (Sc)2 = (Sa c/a)2 + (Sb c/b)2 = (Sa b)2 + (Sb a)2 - outIt->E() = sqrt( pow(inIt->E()*Yfactor, 2) - + pow(correctError*inIt->Y(), 2) ); + const double currentX = histogramData ? (xIn[j] + xIn[j+1])/2.0 : xIn[j]; + // Find out the index of the first correction point after this value + MantidVec::const_iterator pos = std::lower_bound(Xcor.begin(),Xcor.end(),currentX); + const size_t index = pos-Xcor.begin(); + if ( index == Xcor.size() ) + { + // If we're past the end of the correction factors vector, use the last point + Yfactor = Ycor[index-1]; + correctError = Ecor[index-1]; + } + else if (index) + { + // Calculate where between the two closest points our current X value is + const double fraction = (currentX-Xcor[index-1])/(Xcor[index]-Xcor[index-1]); + // Now linearly interpolate to find the correction factors to use + Yfactor = Ycor[index-1] + fraction*(Ycor[index]-Ycor[index-1]); + correctError = Ecor[index-1] + fraction*(Ecor[index]-Ecor[index-1]); + } + else + { + // If we're before the start of the correction factors vector, use the first point + Yfactor = Ycor[0]; + correctError = Ecor[0]; + } + + // Now do the correction on the current point + if (divide) + { + yOut[j] = yIn[j]/Yfactor; + // the proportional error is equal to the sum of the proportional errors + // re-arrange so that you don't get infinity if leftY==0. Sa = error on a, etc. + // c = a/b + // (Sa/a)2 + (Sb/b)2 = (Sc/c)2 + // (Sa c/a)2 + (Sb c/b)2 = (Sc)2 + // = (Sa 1/b)2 + (Sb (a/b2))2 + // (Sc)2 = (1/b)2( (Sa)2 + (Sb a/b)2 ) + eOut[j] = sqrt( pow(eIn[j], 2) + pow( yIn[j]*correctError/Yfactor, 2) )/Yfactor; + } + else + { + yOut[j] = yIn[j]*Yfactor; + // error multiplying two uncorrelated numbers, re-arrange so that you don't get infinity if leftY or rightY == 0 + // Sa = error on a, etc. + // c = a*b + // (Sa/a)2 + (Sb/b)2 = (Sc/c)2 + // (Sc)2 = (Sa c/a)2 + (Sb c/b)2 = (Sa b)2 + (Sb a)2 + eOut[j] = sqrt(pow(eIn[j]*Yfactor, 2) + pow(correctError*yIn[j], 2) ); + } + + + // Copy X value over + xOut[j] = xIn[j]; } - - - // Copy X value over - outIt->X() = inIt->X(); - if (histogramData) outIt->X2() = inIt->X2(); - + if (histogramData) xOut[nbins] = xIn[nbins]; prg.report("CorrectToFile: applying " + operation); } } diff --git a/Code/Mantid/Framework/Algorithms/src/Qxy.cpp b/Code/Mantid/Framework/Algorithms/src/Qxy.cpp index 2a816b7c1648..112f2469e89f 100644 --- a/Code/Mantid/Framework/Algorithms/src/Qxy.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Qxy.cpp @@ -299,12 +299,18 @@ void Qxy::exec() // Count of the number of empty cells - MatrixWorkspace::const_iterator wsIt(*outputWorkspace); + const size_t nhist = outputWorkspace->getNumberHistograms(); + const size_t nbins = outputWorkspace->blocksize(); int emptyBins = 0; - for (;wsIt != wsIt.end(); ++wsIt) + for(size_t i = 0; i < nhist; ++i) { - if (wsIt->Y() < 1.0e-12) ++emptyBins; + const auto & yOut = outputWorkspace->readY(i); + for(size_t j = 0; j < nbins; ++j) + { + if (yOut[j] < 1.0e-12) ++emptyBins; + } } + // Log the number of empty bins g_log.notice() << "There are a total of " << emptyBins << " (" << (100*emptyBins)/(outputWorkspace->size()) << "%) empty Q bins.\n"; diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h index 87ba6fde2e63..f01e260e58c4 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h @@ -50,10 +50,6 @@ namespace DataObjects class DLLExport RebinnedOutput : public Workspace2D { public: - /// Typedef for the workspace_iterator to use with a RebinnedOutput - typedef API::workspace_iterator iterator; - /// Typedef for the const workspace_iterator to use with a RebinnedOutput - typedef API::workspace_iterator const_iterator; /// Class constructor. RebinnedOutput(); diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h index 95956d586fb8..bd407b59a888 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h @@ -53,10 +53,6 @@ namespace DataObjects class DLLExport Workspace2D : public API::MatrixWorkspace { public: - /// Typedef for the workspace_iterator to use with a Workspace2D - typedef API::workspace_iterator iterator; - /// Typedef for the const workspace_iterator to use with a Workspace2D - typedef API::workspace_iterator const_iterator; /** Gets the name of the workspace type diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h index 4321e75174e8..a4fbda2bfcd7 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h @@ -47,10 +47,6 @@ namespace DataObjects class DLLExport WorkspaceSingleValue : public API::MatrixWorkspace { public: - /// Typedef for the workspace_iterator to use with a WorkspaceSingleValue - typedef API::workspace_iterator iterator; - /// Typedef for the const workspace_iterator to use with a WorkspaceSingleValue - typedef API::workspace_iterator const_iterator; /** Gets the name of the workspace type * @return Standard string name */ diff --git a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp index 39dcd3d554c1..f5e476f15f4e 100644 --- a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp +++ b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp @@ -3,8 +3,6 @@ #include "MantidAPI/LocatedDataRef.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/Progress.h" -#include "MantidAPI/WorkspaceIterator.h" -#include "MantidAPI/WorkspaceIteratorCode.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidDataObjects/EventWorkspace.h" @@ -945,10 +943,6 @@ namespace DataObjects } // namespace Mantid -///\cond TEMPLATE -template DLLExport class Mantid::API::workspace_iterator; -template DLLExport class Mantid::API::workspace_iterator; - template DLLExport class Mantid::API::WorkspaceProperty; namespace Mantid From ce04425e90416864444c23850bd8626c74364e04 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 10 Feb 2014 20:31:32 +0000 Subject: [PATCH 054/118] Remove WorkspaceIterator from SaveRKH. Refs #8983 --- .../Framework/DataHandling/src/SaveRKH.cpp | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/SaveRKH.cpp b/Code/Mantid/Framework/DataHandling/src/SaveRKH.cpp index e2ec8c129579..04f8b3686716 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveRKH.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveRKH.cpp @@ -146,7 +146,8 @@ void SaveRKH::writeHeader() void SaveRKH::write1D() { const size_t noDataPoints = m_workspace->size(); - const bool horizontal = (m_workspace->getNumberHistograms() == 1) ? true : false; + const size_t nhist = m_workspace->getNumberHistograms(); + const bool horizontal = (nhist == 1) ? true : false; if (horizontal) { g_log.notice() << "Values in first column are the X values\n"; @@ -156,25 +157,41 @@ void SaveRKH::write1D() else g_log.notice("Values in first column are spectrum numbers"); const bool histogram = m_workspace->isHistogramData(); Progress prg(this,0.0,1.0,noDataPoints); - - MatrixWorkspace::const_iterator wsIt(*m_workspace); - for (int i = 0; wsIt != wsIt.end(); ++wsIt,++i) + const size_t nbins = m_workspace->blocksize(); + + for(size_t i = 0; i < nhist; ++i) { - // Calculate/retrieve the value to go in the first column - double XVal(0.0); - if (horizontal) - XVal = histogram ? (wsIt->X()+wsIt->X2())/2 : wsIt->X(); - else + const auto & xdata = m_workspace->readX(i); + const auto & ydata = m_workspace->readY(i); + const auto & edata = m_workspace->readE(i); + + specid_t specid(0); + try { - try { - XVal = m_workspace->getSpectrum(i)->getSpectrumNo(); - } catch (...) { XVal = i+1; } + specid = m_workspace->getSpectrum(i)->getSpectrumNo(); + } + catch (...) + { + specid = static_cast(i+1); } + + for(size_t j = 0; j < nbins; ++j) + { + // Calculate/retrieve the value to go in the first column + double xval(0.0); + if (horizontal) + xval = histogram ? 0.5*(xdata[j] + xdata[j+1]) : xdata[j]; + else + { + xval = static_cast(specid); + } - m_outRKH << std::fixed << std::setw(12) << std::setprecision(5) << XVal - << std::scientific << std::setw(16) << std::setprecision(6) << wsIt->Y() - << std::setw(16) << wsIt->E() << "\n"; - prg.report(); + m_outRKH << std::fixed << std::setw(12) << std::setprecision(5) << xval + << std::scientific << std::setw(16) << std::setprecision(6) << ydata[j] + << std::setw(16) << edata[j] << "\n"; + + prg.report(); + } } } ///Writes out the 2D data @@ -205,30 +222,40 @@ void SaveRKH::write2D() << std::scientific << std::setprecision(12) << 1.0 << "\n"; const int iflag = 3; m_outRKH << " " << iflag << "(8E12.4)\n"; - // Question over whether I have X & Y swapped over compared to what they're expecting - // First all the data values - MatrixWorkspace::const_iterator wsIt(*m_workspace); - bool requireNewLine = false; - for (int i = 0; wsIt != wsIt.end(); ++wsIt,++i) + + bool requireNewLine = false; + int itemCount(0); + for(size_t i = 0; i < ySize; ++i) { - m_outRKH << std::setw(12) << std::scientific << std::setprecision(4) << wsIt->Y(); - requireNewLine = true; - if ((i+1)%LINE_LENGTH == 0) + const auto & ydata = m_workspace->readY(i); + for(size_t j = 0; j < xSize; ++j) { - m_outRKH << "\n"; - requireNewLine = false; + m_outRKH << std::setw(12) << std::scientific << std::setprecision(4) << ydata[j]; + requireNewLine = true; + if ((itemCount+1) % LINE_LENGTH == 0) + { + m_outRKH << "\n"; + requireNewLine = false; + } + ++itemCount; } } // extra new line is required if number of data written out in last column is // less than LINE_LENGTH if ( requireNewLine ) m_outRKH << "\n"; + // Then all the error values - wsIt.begin(); - for (int i = 0; wsIt != wsIt.end(); ++wsIt,++i) + itemCount = 0; + for(size_t i = 0; i < ySize; ++i) { - m_outRKH << std::setw(12) << std::scientific << std::setprecision(4) << wsIt->E(); - if ((i+1)%LINE_LENGTH == 0) m_outRKH << "\n"; + const auto & edata = m_workspace->readE(i); + for(size_t j = 0; j < xSize; ++j) + { + m_outRKH << std::setw(12) << std::scientific << std::setprecision(4) << edata[j]; + if ((itemCount+1) % LINE_LENGTH == 0) m_outRKH << "\n"; + ++itemCount; + } } } From c9d93ec2c6e16aca94c8412ed9b9ab726bda06e4 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 10 Feb 2014 20:42:03 +0000 Subject: [PATCH 055/118] Remove workspace iterators from UserAlgorithms Refs #8983 --- .../Framework/UserAlgorithms/ModifyData.cpp | 93 +++++++------------ .../UserAlgorithms/WorkspaceAlgorithm.cpp | 31 +++---- 2 files changed, 46 insertions(+), 78 deletions(-) diff --git a/Code/Mantid/Framework/UserAlgorithms/ModifyData.cpp b/Code/Mantid/Framework/UserAlgorithms/ModifyData.cpp index ae9ba1baf078..67e9b5f54edd 100644 --- a/Code/Mantid/Framework/UserAlgorithms/ModifyData.cpp +++ b/Code/Mantid/Framework/UserAlgorithms/ModifyData.cpp @@ -37,8 +37,8 @@ void ModifyData::init() */ void ModifyData::exec() { - // g_log is a reference to the logger. It is used to print out information, - // warning, and error messages + // g_log is a reference to the logger. It is used to print out information, + // warning, and error messages g_log.information() << "Running algorithm " << name() << " version " << version() << std::endl; // Get the input workspace @@ -47,61 +47,30 @@ void ModifyData::exec() // make output Workspace the same type and size as the input one MatrixWorkspace_sptr outputW = WorkspaceFactory::Instance().create(inputW); - bool useVectors = getProperty("UseVectors"); - - if ( useVectors ) + g_log.information() << "Option 1. Original values:" << std::endl; + // Get the count of histograms in the input workspace + size_t histogramCount = inputW->getNumberHistograms(); + // Loop over spectra + for (size_t i = 0; i < histogramCount; ++i) { - g_log.information() << "Option 1. Original values:" << std::endl; - // Get the count of histograms in the input workspace - size_t histogramCount = inputW->getNumberHistograms(); - // Loop over spectra - for (size_t i = 0; i < histogramCount; ++i) - { - // Retrieve the data into a vector - const MantidVec& XValues = inputW->readX(i); - const MantidVec& YValues = inputW->readY(i); - const MantidVec& EValues = inputW->readE(i); - MantidVec& newX = outputW->dataX(i); - MantidVec& newY = outputW->dataY(i); - MantidVec& newE = outputW->dataE(i); - - // Iterate over i-th spectrum and modify the data - for(size_t j=0; jblocksize(); j++) - { - g_log.information() << "Spectrum " << i << " Point " << j << " values: " - << XValues[j] << ' ' << YValues[j] << ' ' << EValues[j] << std::endl; - newX[j] = XValues[j] + static_cast(i + j); - newY[j] = YValues[j]*(2. + 0.1*static_cast(j)); - newE[j] = EValues[j]+0.1; - } - } + // Retrieve the data into a vector + MantidVec& newX = outputW->dataX(i); + MantidVec& newY = outputW->dataY(i); + MantidVec& newE = outputW->dataE(i); + const MantidVec& XValues = inputW->readX(i); + const MantidVec& YValues = inputW->readY(i); + const MantidVec& EValues = inputW->readE(i); + + // Iterate over i-th spectrum and modify the data + for(size_t j=0; jblocksize(); j++) + { + g_log.information() << "Spectrum " << i << " Point " << j << " values: " + << XValues[j] << ' ' << YValues[j] << ' ' << EValues[j] << std::endl; + newX[j] = XValues[j] + static_cast(i + j); + newY[j] = YValues[j]*(2. + 0.1*static_cast(j)); + newE[j] = EValues[j]+0.1; + } } - else - { - g_log.information() << "Option 2. Original values:" << std::endl; - // Iterate over the workspace and modify the data - int count = 0; - MatrixWorkspace::iterator ti_out(*outputW); - for(MatrixWorkspace::const_iterator ti(*inputW); ti != ti.end(); ++ti,++ti_out) - { - // get the spectrum number - size_t i = count / inputW->blocksize(); - // get the point number - size_t j = count % inputW->blocksize(); - // Get the reference to a data point - LocatedDataRef tr = *ti; - LocatedDataRef tr_out = *ti_out; - g_log.information() << "Spectrum " << i << " Point " << j << " values: " - << tr.X() << ' ' << tr.Y() << ' ' << tr.E() << std::endl; - tr_out.X() = tr.X() + count; - tr_out.Y() = tr.Y()*2; - tr_out.E() = tr.E()+0.1; - - count++; - } - - } - // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); @@ -112,14 +81,20 @@ void ModifyData::exec() // Check the new workspace g_log.information() << "New values:" << std::endl; int count = 0; - for(MatrixWorkspace::const_iterator ti(*newW); ti != ti.end(); ++ti) + for(size_t i = 0; i < histogramCount; ++i) { + const MantidVec& XValues = outputW->readX(i); + const MantidVec& YValues = outputW->readY(i); + const MantidVec& EValues = outputW->readE(i); + + for(size_t j = 0; j < outputW->blocksize(); ++j) + { // Get the reference to a data point - LocatedDataRef tr = *ti; g_log.information() << "Point number " << count++ << " values: " - << tr.X() << ' ' << tr.Y() << ' ' << tr.E() << std::endl; + << XValues[j] << ' ' << YValues[j] << ' ' << EValues[j] << std::endl; + } } - + } } diff --git a/Code/Mantid/Framework/UserAlgorithms/WorkspaceAlgorithm.cpp b/Code/Mantid/Framework/UserAlgorithms/WorkspaceAlgorithm.cpp index 69deb90c3724..578e0933be9c 100644 --- a/Code/Mantid/Framework/UserAlgorithms/WorkspaceAlgorithm.cpp +++ b/Code/Mantid/Framework/UserAlgorithms/WorkspaceAlgorithm.cpp @@ -31,9 +31,9 @@ void WorkspaceAlgorithm::init() */ void WorkspaceAlgorithm::exec() { - // g_log is a reference to the logger. It is used to print out information, - // warning, and error messages - g_log.information() << "Running algorithm " << name() << " version " << version() << std::endl; + // g_log is a reference to the logger. It is used to print out information, + // warning, and error messages + g_log.information() << "Running algorithm " << name() << " version " << version() << std::endl; // Get the input workspace MatrixWorkspace_const_sptr workspace = getProperty("Workspace"); @@ -42,26 +42,19 @@ void WorkspaceAlgorithm::exec() g_log.information() << "Number of items = " << workspace->size() << std::endl; int count = 0; - // Iterate over the workspace - for(MatrixWorkspace::const_iterator ti(*workspace); ti != ti.end(); ++ti) + size_t histogramCount = workspace->getNumberHistograms(); + for(size_t i = 0; i < histogramCount; ++i) { - // Get the reference to a data point - LocatedDataRef tr = *ti; - g_log.information() << "Point number " << count++ << " values: " - << tr.X() << ' ' << tr.Y() << ' ' << tr.E() << std::endl; - } + const MantidVec& XValues = workspace->readX(i); + const MantidVec& YValues = workspace->readY(i); + const MantidVec& EValues = workspace->readE(i); - count = 0; - int loopCount = 2; - // Do several loops - for(MatrixWorkspace::const_iterator ti(*workspace,loopCount,LoopOrientation::Horizontal); ti != ti.end(); ++ti) - { - // Get the reference to a data point - LocatedDataRef tr = *ti; + for(size_t j = 0; j < workspace->blocksize(); ++j) + { g_log.information() << "Point number " << count++ << " values: " - << tr.X() << ' ' << tr.Y() << ' ' << tr.E() << std::endl; + << XValues[j] << ' ' << YValues[j] << ' ' << EValues[j] << std::endl; + } } - } } From 03eb920f2286e355c3b1ad9f908123fef3fa9b0c Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 10 Feb 2014 20:55:11 +0000 Subject: [PATCH 056/118] Remove WorkspaceIterator code Refs #8983 --- Code/Mantid/Framework/API/CMakeLists.txt | 8 - .../Framework/API/inc/MantidAPI/IDataItem.h | 52 ---- .../API/inc/MantidAPI/ILocatedData.h | 55 ---- .../API/inc/MantidAPI/LocatedDataRef.h | 77 ----- .../API/inc/MantidAPI/LocatedDataValue.h | 78 ----- .../API/inc/MantidAPI/WorkspaceIterator.h | 230 -------------- .../API/inc/MantidAPI/WorkspaceIteratorCode.h | 282 ------------------ .../Framework/API/src/IEventWorkspace.cpp | 8 +- .../Framework/API/src/LocatedDataRef.cpp | 226 -------------- .../Framework/API/src/LocatedDataValue.cpp | 234 --------------- .../src/ManagedRawFileWorkspace2D.cpp | 3 - .../DataObjects/src/EventWorkspace.cpp | 1 - .../Framework/DataObjects/src/Workspace2D.cpp | 6 - .../DataObjects/src/WorkspaceSingleValue.cpp | 5 - 14 files changed, 1 insertion(+), 1264 deletions(-) delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/IDataItem.h delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/ILocatedData.h delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/LocatedDataRef.h delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/LocatedDataValue.h delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceIterator.h delete mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceIteratorCode.h delete mode 100644 Code/Mantid/Framework/API/src/LocatedDataRef.cpp delete mode 100644 Code/Mantid/Framework/API/src/LocatedDataValue.cpp diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index fd1c917fb591..0f37b0be4e40 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -69,8 +69,6 @@ set ( SRC_FILES src/JointDomain.cpp src/LinearScale.cpp src/LiveListenerFactory.cpp - src/LocatedDataRef.cpp - src/LocatedDataValue.cpp src/LogManager.cpp src/LogarithmScale.cpp src/MDGeometry.cpp @@ -174,7 +172,6 @@ set ( INC_FILES inc/MantidAPI/ICatalogInfoService.h inc/MantidAPI/IConstraint.h inc/MantidAPI/ICostFunction.h - inc/MantidAPI/IDataItem.h inc/MantidAPI/IDomainCreator.h inc/MantidAPI/IEventList.h inc/MantidAPI/IEventWorkspace.h @@ -187,7 +184,6 @@ set ( INC_FILES inc/MantidAPI/IFunctionValues.h inc/MantidAPI/IFunctionWithLocation.h inc/MantidAPI/ILiveListener.h - inc/MantidAPI/ILocatedData.h inc/MantidAPI/IMDEventWorkspace.h inc/MantidAPI/IMDHistoWorkspace.h inc/MantidAPI/IMDIterator.h @@ -217,8 +213,6 @@ set ( INC_FILES inc/MantidAPI/JointDomain.h inc/MantidAPI/LinearScale.h inc/MantidAPI/LiveListenerFactory.h - inc/MantidAPI/LocatedDataRef.h - inc/MantidAPI/LocatedDataValue.h inc/MantidAPI/LogManager.h inc/MantidAPI/LogarithmScale.h inc/MantidAPI/MDGeometry.h @@ -260,8 +254,6 @@ set ( INC_FILES inc/MantidAPI/WorkspaceFactory.h inc/MantidAPI/WorkspaceGroup.h inc/MantidAPI/WorkspaceHistory.h - inc/MantidAPI/WorkspaceIterator.h - inc/MantidAPI/WorkspaceIteratorCode.h inc/MantidAPI/WorkspaceOpOverloads.h inc/MantidAPI/WorkspaceProperty.h inc/MantidAPI/WorkspaceValidators.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IDataItem.h b/Code/Mantid/Framework/API/inc/MantidAPI/IDataItem.h deleted file mode 100644 index 7c7391cbf46f..000000000000 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IDataItem.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef MANTIDAPI_IDATAITEM_H -#define MANTIDAPI_IDATAITEM_H - -#include "MantidAPI/DllConfig.h" - -namespace Mantid -{ -namespace API -{ -/** - Interface IDataItem of a Y and error value. - - \author N. Draper - - Copyright © 2007-8 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_API_DLL IDataItem -{ - public: - virtual const double& Y() const =0; ///< Returns the Y value - virtual const double& E() const =0; ///< Returns the E value - - virtual double& Y() =0; ///< Returns the Y value - virtual double& E() =0; ///< Returns the E value - - ///virtual destructor - virtual ~IDataItem() - {} -}; - -} // NAMESPACE API - -} // NAMESPACE Mantid - -#endif //MANTIDAPI_IDATAITEM_H diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ILocatedData.h b/Code/Mantid/Framework/API/inc/MantidAPI/ILocatedData.h deleted file mode 100644 index 818c1f42a172..000000000000 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ILocatedData.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef MANTIDAPI_ILOCATEDDATA_H -#define MANTIDAPI_ILOCATEDDATA_H - -#include "MantidAPI/DllConfig.h" -#include "MantidAPI/IDataItem.h" - -namespace Mantid -{ -namespace API -{ -/** - Interface ILocatedData describes a single data item of a point data dataset. - - \author N. Draper - - Copyright © 2007-8 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ - class MANTID_API_DLL ILocatedData : public IDataItem -{ - public: - - virtual const double& X() const =0; ///< Returns the X value - virtual double& X() =0; ///< Returns the X value - - virtual const double& X2() const =0; ///< Returns the X value of the end of the histogram bin - virtual double& X2() =0; ///< Returns the X value of the end of the histogram bin - - virtual bool isHistogram() const =0; ///. - - File change history is stored at: -*/ - class MANTID_API_DLL LocatedDataRef : public ILocatedData -{ - public: - const double& X() const; - const double& E() const; - - double& X(); - double& E(); - - const double& Y() const; - double& Y(); - - const double& X2() const; ///< Returns the X value of the end of the histogram bin - double& X2(); ///< Returns the X value of the end of the histogram bin - - bool isHistogram() const; ///(const LocatedDataRef&) const; - int operator==(const LocatedDataRef&) const; - int operator!=(const LocatedDataRef&) const; -}; - -} // NAMESPACE API - -} // NAMESPACE Mantid - -#endif //MANTIDAPI_LOCATEDDATAREF_H diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/LocatedDataValue.h b/Code/Mantid/Framework/API/inc/MantidAPI/LocatedDataValue.h deleted file mode 100644 index a622861bd4ba..000000000000 --- a/Code/Mantid/Framework/API/inc/MantidAPI/LocatedDataValue.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef MANTIDAPI_LOCATEDDATAVALUE_H -#define MANTIDAPI_LOCATEDDATAVALUE_H - -#include "MantidAPI/DllConfig.h" -#include "MantidAPI/ILocatedData.h" - -namespace Mantid -{ - namespace API - { - /** - IDataItem of a Y and error value, together with a pointer to an ErrorHelper. - - \author N. Draper - - Copyright © 2007-8 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - */ - class MANTID_API_DLL LocatedDataValue : public ILocatedData - { - public: - - const double& X() const; - const double& E() const; - - double& X(); - double& E(); - - const double& Y() const; - double& Y(); - - double xValue; ///< value of X - double yValue; ///< value of Y - double eValue; ///< value of E - - const double& X2() const; - double& X2(); - - bool isHistogram() const; ///(const LocatedDataValue&) const; - int operator==(const LocatedDataValue&) const; - int operator!=(const LocatedDataValue&) const; - private: - bool _isHistogram; ///< True if the data is a histogram - }; - - } // NAMESPACE API - -} // NAMESPACE Mantid - -#endif //MANTIDAPI_LOCATEDDATAVALUE_H diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceIterator.h b/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceIterator.h deleted file mode 100644 index 8dce81b2e4a3..000000000000 --- a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceIterator.h +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef MANTIDAPI_WORKSPACE_ITERATOR_H -#define MANTIDAPI_WORKSPACE_ITERATOR_H - -#include -#include "MantidAPI/DllConfig.h" -#include "MantidAPI/LocatedDataRef.h" - -namespace Mantid -{ -namespace API -{ -/** - workspace_iterator iterates over a workspace providing values as TripleRefs - - \class workspace_iterator - \author S. Ansell - \date November 2007 - \version 1.0 - - Copyright © 2007-8 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: -*/ -template -class DLLExport workspace_iterator -{ -private: - ///internal workspace pointer - _Container * const m_workspace; - /// pointer to a TripleRef of doubles - LocatedDataRef m_CPoint; - - ///The number of times this iterator should loop before ending - int m_loopCount; - ///The number of times this iterator should loop before ending - const unsigned int m_loopOrientation; - /// internal index of location within the workspace - std::size_t m_index; - ///Internal cache of the workspace size - std::size_t m_wsSize; - ///Internal cache of the workspace blocksize - std::size_t m_blocksize; - - ///Internal cache of the current datablock index - std::size_t m_dataBlockIndex; - ///Internal cache of the current datablock index minimum value - std::size_t m_blockMin; - ///Internal cache of the current datablock index maximum value - std::size_t m_blockMax; - ///Internal flag to indicate if the X2 value is present - bool m_IsX2Present; - - /// @cond - template - struct internal_iterator_type {}; - - template - struct internal_iterator_type - { - typedef std::vector::iterator iterator_type; - }; - - template - struct internal_iterator_type - { - typedef std::vector::const_iterator iterator_type; - }; - /// @endcond - - /// Makes the underlying std::vector iterator be const or not according to whether the workspace_iterator is (or not). - typedef typename internal_iterator_type<_Iterator*>::iterator_type iterator_type; - - ///Internal cache of X iterator for current datablock - iterator_type it_dataX; - ///Internal cache of Y iterator for current datablock - iterator_type it_dataY; - ///Internal cache of E iterator for current datablock - iterator_type it_dataE; - - ///Validates the index and updates the current m_CPoint - void validateIndex(); - - ///Validates the index and updates the current m_CPoint - bool isWorkspaceHistogram(); - -public: - /// @cond - typedef typename std::iterator_traits<_Iterator*>::iterator_category iterator_category; - typedef typename std::iterator_traits<_Iterator*>::value_type value_type; - typedef typename std::iterator_traits<_Iterator*>::difference_type difference_type; - typedef typename std::iterator_traits<_Iterator*>::reference reference; - typedef typename std::iterator_traits<_Iterator*>::pointer pointer; - /// @endcond - - workspace_iterator(); - workspace_iterator(_Container&); - workspace_iterator(_Container&, int loopCount); - workspace_iterator(_Container&, int loopCount, const unsigned int loopOrientation); - workspace_iterator(const workspace_iterator&); - - reference operator*() { return m_CPoint; } ///< Base Accessor - pointer operator->() { return &m_CPoint; } ///< Base Pointer accessor - /// Random accessor - reference operator[](const difference_type& N) - { - m_index=N; - validateIndex(); - return m_CPoint; - } - - workspace_iterator& operator++(); - workspace_iterator operator++(int); - workspace_iterator& operator--(); - workspace_iterator operator--(int); - workspace_iterator& operator+=(difference_type); - workspace_iterator& operator-=(difference_type); - workspace_iterator operator+(difference_type) const; - workspace_iterator operator-(difference_type) const; - difference_type operator-(const workspace_iterator&) const; - - /** - lessthan operator - @param A :: Iterator to compare - @return status - */ - bool operator<(const workspace_iterator& A) const - { - if (!m_workspace) - return 0; - if (!A.m_workspace) - return 1; - return (m_index -#include - -#include "MantidAPI/LocatedDataRef.h" - -namespace Mantid -{ - namespace API - { - /** - Null constructor - */ - template - workspace_iterator<_Iterator, _Container>::workspace_iterator() : - m_workspace(0),m_CPoint(),m_loopCount(1),m_loopOrientation(1), - m_index(0),m_wsSize(0),m_blocksize(0),m_blockMin((std::size_t)-1), - m_blockMax((std::size_t)-1),m_IsX2Present(false) - {} - - /** - Workspace based constructor - @param WA :: Workspace to take pointer - */ - template - workspace_iterator<_Iterator, _Container>::workspace_iterator(_Container& WA) : - m_workspace(&WA),m_CPoint(),m_loopCount(1),m_loopOrientation(0),m_index(0), - m_wsSize(m_workspace->size()),m_blocksize(m_workspace->blocksize()), - m_blockMin((std::size_t)-1),m_blockMax((std::size_t)-1),m_IsX2Present(false) - { - - m_IsX2Present = isWorkspaceHistogram(); - validateIndex(); - } - - /** - Multiple loop workspace based constructor - @param WA :: Workspace to take pointer - @param loopCount :: The number of time this iterator should loop over the same data before stopping. - */ - template - workspace_iterator<_Iterator, _Container>::workspace_iterator(_Container& WA, int loopCount) : - m_workspace(&WA),m_CPoint(),m_loopCount(loopCount),m_loopOrientation(0),m_index(0), - m_wsSize(m_workspace->size()),m_blocksize(m_workspace->blocksize()),m_blockMin((std::size_t)-1), - m_blockMax((std::size_t)-1),m_IsX2Present(false) - { - - m_IsX2Present = isWorkspaceHistogram(); - //pretend that the container is longer than it is by multiplying its size by the loopcount - m_wsSize *= m_loopCount; - validateIndex(); - } - - /** - Multiple loop workspace based constructor also specifying the loop orientation - @param WA :: Workspace to take pointer - @param loopCount :: The number of time this iterator should loop over the same data before stopping. - @param loopOrientation :: true = vertical, false = horizontal. - */ - template - workspace_iterator<_Iterator, _Container>::workspace_iterator(_Container& WA, int loopCount, const unsigned int loopOrientation) : - m_workspace(&WA),m_CPoint(),m_loopCount(loopCount),m_loopOrientation(loopOrientation),m_index(0), - m_wsSize(m_workspace->size()),m_blocksize(m_workspace->blocksize()),m_blockMin((std::size_t)-1), - m_blockMax((std::size_t)-1),m_IsX2Present(false) - { - - m_IsX2Present = isWorkspaceHistogram(); - //pretend that the container is longer than it is by multiplying its size by the loopcount - m_wsSize *= m_loopCount; - validateIndex(); - } - - /** - Copy constructor - @param A :: workspace_iterator to copy - */ - template - workspace_iterator<_Iterator, _Container>::workspace_iterator(const workspace_iterator<_Iterator, _Container>& A) : - m_workspace(A.m_workspace),m_CPoint(A.m_CPoint),m_loopCount(A.m_loopCount),m_loopOrientation(A.m_loopOrientation), - m_index(A.m_index),m_wsSize(A.m_wsSize),m_blocksize(A.m_blocksize),m_blockMin(A.m_blockMin),m_blockMax(A.m_blockMax), - m_IsX2Present(A.m_IsX2Present),it_dataX(A.it_dataX),it_dataY(A.it_dataY),it_dataE(A.it_dataE) - { - validateIndex(); - } - - /** - Validate the index - */ - template - void workspace_iterator<_Iterator, _Container>::validateIndex() - { - if (!m_workspace) - m_index=0; - else if (m_index>m_wsSize) - m_index=m_wsSize; - if (!m_workspace) - { - return; - } - - if (m_index != m_wsSize ) - { - if (m_index > m_blockMax || m_index < m_blockMin ) - { - m_dataBlockIndex = m_index/m_blocksize; - m_blockMin = m_index - (m_index % m_blocksize); - m_blockMax = m_blockMin + m_blocksize -1; - - //make sure you get the right block if you are looping multiple times - if (m_loopCount != 1) - { - if (m_loopOrientation) - { - //vertical Orientation we want to loop over each index value loopcount times. - m_dataBlockIndex = m_index/(m_blocksize*m_loopCount); - m_blockMin = m_index - (m_index % (m_blocksize*m_loopCount)); - m_blockMax = m_blockMin + (m_blocksize*m_loopCount) -1; - } - else - { - //Horizontal Orientation we want to loop over the same datablock loopcount times. - std::size_t realWsSize = m_wsSize/m_loopCount; - m_dataBlockIndex = (m_index % realWsSize)/m_blocksize; - } - } - - //get cached block level data objects - it_dataX = m_workspace->dataX(m_dataBlockIndex).begin(); - it_dataY = m_workspace->dataY(m_dataBlockIndex).begin(); - it_dataE = m_workspace->dataE(m_dataBlockIndex).begin(); - } - size_t iteratorPos; - if ((m_loopCount != 1) && (m_loopOrientation)) - { - //vertical Orientation we want to loop over each index value loopcount times. - // and never change the blockindex - iteratorPos = (m_index-m_blockMin)/m_loopCount; - } - else - { - iteratorPos = m_index-m_blockMin; - } - // const_cast is needed for the const_iterator (does nothing otherwise) - m_CPoint.xPointer = const_cast(&(it_dataX[iteratorPos])); - m_CPoint.yPointer = const_cast(&(it_dataY[iteratorPos])); - m_CPoint.ePointer = const_cast(&(it_dataE[iteratorPos])); - if(m_IsX2Present) - { - m_CPoint.x2Pointer = const_cast(&(it_dataX[iteratorPos+1])); - } - } - } - - /** - Addition to index - @param N :: Number to add - @return Iterator advanced by N - */ - template - workspace_iterator<_Iterator, _Container> workspace_iterator<_Iterator, _Container>::operator+(difference_type N) const - { - workspace_iterator<_Iterator, _Container> Out(*this); - Out+=N; - return Out; - } - - /** - Negation to index - @param N :: Number to subtract - @return Iterator decreased by N - */ - template - workspace_iterator<_Iterator, _Container> workspace_iterator<_Iterator, _Container>::operator-(difference_type N) const - { - workspace_iterator<_Iterator, _Container> Out(*this); - Out-=N; - return Out; - } - - /** - Addition to self by N - @param N :: Number to add to index - @return *this - */ - template - workspace_iterator<_Iterator, _Container>& workspace_iterator<_Iterator, _Container>::operator+=(difference_type N) - { - m_index+=N; - validateIndex(); - return *this; - } - - /** - Negation to self by N - @param N :: Number to subtract - @return *this - */ - template - workspace_iterator<_Iterator, _Container>& workspace_iterator<_Iterator, _Container>::operator-=(difference_type N) - { - m_index-=N; - validateIndex(); - return *this; - } - - /** - Increment iterator (pre) - @return Iterator - */ - template - workspace_iterator<_Iterator, _Container>& workspace_iterator<_Iterator, _Container>::operator++() - { - ++m_index; - validateIndex(); - return *this; - } - - /** - Decrement iterator (pre) - @return Iterator - */ - template - workspace_iterator<_Iterator, _Container>& workspace_iterator<_Iterator, _Container>::operator--() - { - --m_index; - validateIndex(); - return *this; - } - - /** - Increment iterator (post) - @return Iterator before increment - */ - template - workspace_iterator<_Iterator, _Container> workspace_iterator<_Iterator, _Container>::operator++(int) - { - workspace_iterator<_Iterator, _Container> Out(*this); - this->operator++(); - return Out; - } - - /** - Negation iterator (post) - @return Iterator before decrement - */ - template - workspace_iterator<_Iterator, _Container> workspace_iterator<_Iterator, _Container>::operator--(int) - { - workspace_iterator<_Iterator, _Container> Out(*this); - this->operator--(); - return Out; - } - - /** - Difference iterator - @return difference (as a non-inclusive count) - */ - template - typename std::iterator_traits<_Iterator*>::difference_type workspace_iterator<_Iterator, _Container>::operator-(const workspace_iterator<_Iterator, _Container>& A) const - { - if (!m_workspace && !A.m_workspace) - return 0; - if (!m_workspace) /// This effectively an end - return A.m_wsSize-A.m_index; - if (!A.m_workspace) /// A effectively an end - return m_index-m_wsSize; - return A.m_index-m_index; - } - - template - bool workspace_iterator<_Iterator, _Container>::isWorkspaceHistogram() - { - if (m_wsSize > 0) - { - return (m_workspace->dataX(0).size() > m_workspace->dataY(0).size()); - } - return false; - } - - - } // NAMESPACE API - -} // NAMESPACE Mantid diff --git a/Code/Mantid/Framework/API/src/IEventWorkspace.cpp b/Code/Mantid/Framework/API/src/IEventWorkspace.cpp index b0c78ec47085..9dc619305ac3 100644 --- a/Code/Mantid/Framework/API/src/IEventWorkspace.cpp +++ b/Code/Mantid/Framework/API/src/IEventWorkspace.cpp @@ -2,13 +2,6 @@ // Includes //------------------------------------------------------ #include "MantidAPI/IEventWorkspace.h" -#include "MantidAPI/LocatedDataRef.h" -#include "MantidAPI/WorkspaceIterator.h" -#include "MantidAPI/WorkspaceIteratorCode.h" - -///\cond TEMPLATE -template MANTID_API_DLL class Mantid::API::workspace_iterator; -template MANTID_API_DLL class Mantid::API::workspace_iterator; namespace Mantid { @@ -41,6 +34,7 @@ const std::string IEventWorkspace::toString() const } +///\cond TEMPLATE /* * In order to be able to cast PropertyWithValue classes correctly a definition for the PropertyWithValue is required * diff --git a/Code/Mantid/Framework/API/src/LocatedDataRef.cpp b/Code/Mantid/Framework/API/src/LocatedDataRef.cpp deleted file mode 100644 index d515db54fae7..000000000000 --- a/Code/Mantid/Framework/API/src/LocatedDataRef.cpp +++ /dev/null @@ -1,226 +0,0 @@ -#include "MantidAPI/LocatedDataRef.h" -#include "MantidKernel/Exception.h" -namespace Mantid -{ - - namespace API - { - - /** - Standard Copy Constructor - @param A :: LocatedDataRef Item to copy - */ - LocatedDataRef::LocatedDataRef(const LocatedDataRef& A) : ILocatedData(), - xPointer(A.xPointer),x2Pointer(A.x2Pointer),yPointer(A.yPointer),ePointer(A.ePointer) - {} - - /// Default constructor - LocatedDataRef::LocatedDataRef(): ILocatedData(), - xPointer(0),x2Pointer(0),yPointer(0),ePointer(0) - {} - - /** - Standard Assignment Constructor - @param A :: LocatedDataRef Item to copy - @return *this - */ - LocatedDataRef& LocatedDataRef::operator=(const LocatedDataRef& A) - { - if (this!=&A) - { - *xPointer= *A.xPointer; - *yPointer= *A.yPointer; - *ePointer= *A.ePointer; - if (A.x2Pointer) - { - *x2Pointer= *A.x2Pointer; - } - } - return *this; - } - - /** - Standard Assignment Constructor - @param A :: ILocatedData Item to copy - @return *this - */ - LocatedDataRef& LocatedDataRef::operator=(const ILocatedData& A) - { - if (this!=&A) - { - *xPointer= A.X(); - *yPointer= A.Y(); - *ePointer= A.E(); - if(x2Pointer) - { - *x2Pointer= A.X2(); - } - } - return *this; - } - - /** - Standard Destructor - */ - LocatedDataRef::~LocatedDataRef() - { - //do not delete the contents as they are managed by the collection. - } - - - /** - Operator== all components must be equal - @param A :: Other object to compare - */ - int LocatedDataRef::operator==(const LocatedDataRef& A) const - { - return (*xPointer!=*A.xPointer || *yPointer!=*A.yPointer || - *ePointer!=*A.ePointer) ? 0 : 1; - } - - /** - Operator!= any component is not equal - @param A :: Other object to compare - @return this!=A - */ - int LocatedDataRef::operator!=(const LocatedDataRef& A) const - { - return (*xPointer==*A.xPointer && *yPointer == *A.yPointer && - *ePointer== *A.ePointer) ? 0 : 1; - } - - /** - Operator< takes xPointer to last precidence. - @param A :: LocatedDataRef to compare - @return this < A - */ - int LocatedDataRef::operator<(const LocatedDataRef& A) const - { - if (&A!=this) - { - if (*xPointer> *A.xPointer) - return 0; - if (*xPointer< *A.xPointer) - return 1; - if (*yPointer> *A.yPointer) - return 0; - if (*yPointer< *A.yPointer) - return 1; - if (*ePointer > *A.ePointer) - return 0; - if (*yPointer< *A.yPointer) - return 1; - } - return 0; - } - - /** - Operator> takes xPointer to last precidence. - Uses operator< to obtain value. - Note it does not uses 1-(A A - */ - int LocatedDataRef::operator>(const LocatedDataRef& A) const - { - return !(this->operator<(A)); - } - - /** Const Accessor for X value - @return The X value - */ - const double& LocatedDataRef::X() const - { - return *xPointer; - } - - /** Accessor for X value - @return The X value - */ - double& LocatedDataRef::X() - { - return *xPointer; - } - - /** Const Accessor for Y value - @return The Y value - */ - const double& LocatedDataRef::Y() const - { - return *yPointer; - } - - /** Accessor for Y value - @return The Y value - */ - double& LocatedDataRef::Y() - { - return *yPointer; - } - - /** Const Accessor for E value - @return The E value - */ - const double& LocatedDataRef::E() const - { - return *ePointer; - } - - /** Accessor for E value - @return The E value - */ - double& LocatedDataRef::E() - { - return *ePointer; - } - - /** Const Accessor for X2 value, this should only be used if isHistogram() == true - @return The X2 value - */ - const double& LocatedDataRef::X2() const - { - if (isHistogram()) - { - return *x2Pointer; - } - else - { - throw Kernel::Exception::NotFoundError("X2 value is not set, check isHistogram() before accessing X2","X2"); - } - } - - /** Accessor for X2 value, this should only be used if isHistogram() == true - @return The X2 value - */ - double& LocatedDataRef::X2() - { - if (isHistogram()) - { - return *x2Pointer; - } - else - { - throw Kernel::Exception::NotFoundError("X2 value is not set, check isHistogram() before accessing X2","X2"); - } - } - - /** Returns true if the data point is hastogram data and therefore has an X2. - @returns true if the X2 value is present - */ - bool LocatedDataRef::isHistogram() const - { - return (x2Pointer!=0); - } - - - /** Clone method - * Make a copy of the LocatedDataRef - * @return new(*this) - */ - LocatedDataRef* LocatedDataRef::clone() const - { - return new LocatedDataRef(*this); - } - } // NAMESPACE API - -} // NAMESPACE Mantid diff --git a/Code/Mantid/Framework/API/src/LocatedDataValue.cpp b/Code/Mantid/Framework/API/src/LocatedDataValue.cpp deleted file mode 100644 index 490dd7c002fe..000000000000 --- a/Code/Mantid/Framework/API/src/LocatedDataValue.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "MantidAPI/LocatedDataValue.h" -#include "MantidKernel/Exception.h" - -namespace Mantid -{ - - namespace API - { - - /** - Standard Copy Constructor - @param A :: LocatedDataValue Item to copy - */ - LocatedDataValue::LocatedDataValue(const LocatedDataValue& A) : ILocatedData(), - xValue(A.xValue),yValue(A.yValue),eValue(A.eValue), - x2Value(A.x2Value),_isHistogram(A._isHistogram) - {} - - /** - Standard Copy Constructor - @param A :: LocatedDataValue Item to copy - */ - LocatedDataValue::LocatedDataValue(const ILocatedData& A) : ILocatedData(), - xValue(A.X()),yValue(A.Y()),eValue(A.E()), - x2Value(0),_isHistogram(A.isHistogram()) - { - if (isHistogram()) - { - x2Value = A.X2(); - } - } - - /// Default constructor - LocatedDataValue::LocatedDataValue(): ILocatedData(), - xValue(0),yValue(0),eValue(0) - {} - - /** - Standard Assignment Constructor - @param A :: LocatedDataValue Item to copy - @return *this - */ - LocatedDataValue& LocatedDataValue::operator=(const LocatedDataValue& A) - { - if (this!=&A) - { - xValue= A.xValue; - x2Value= A.x2Value; - yValue= A.yValue; - eValue= A.eValue; - _isHistogram = A._isHistogram; - } - return *this; - } - - /** - Standard Assignment Constructor - @param A :: ILocatedData Item to copy - @return *this - */ - LocatedDataValue& LocatedDataValue::operator=(const ILocatedData& A) - { - if (this!=&A) - { - xValue= A.X(); - _isHistogram = A.isHistogram(); - if (_isHistogram) - { - x2Value= A.X2(); - } - - yValue= A.Y(); - eValue= A.E(); - } - return *this; - } - - /** - Standard Destructor - */ - LocatedDataValue::~LocatedDataValue() - { - } - - - /** - Operator== all components must be equal - @param A :: Other object to compare - */ - int LocatedDataValue::operator==(const LocatedDataValue& A) const - { - return (xValue!=A.xValue || x2Value!=A.x2Value || yValue!=A.yValue || - eValue!=A.eValue) ? 0 : 1; - } - - /** - Operator!= any component is not equal - @param A :: Other object to compare - @return this!=A - */ - int LocatedDataValue::operator!=(const LocatedDataValue& A) const - { - return (xValue==A.xValue && x2Value==A.x2Value && yValue == A.yValue && - eValue== A.eValue) ? 0 : 1; - } - - /** - Operator< takes xValue to last precidence. - @param A :: LocatedDataValue to compare - @return this < A - */ - int LocatedDataValue::operator<(const LocatedDataValue& A) const - { - if (&A!=this) - { - if (xValue> A.xValue) - return 0; - if (xValue< A.xValue) - return 1; - if (x2Value> A.x2Value) - return 0; - if (x2Value< A.x2Value) - return 1; - if (yValue> A.yValue) - return 0; - if (yValue< A.yValue) - return 1; - if (eValue > A.eValue) - return 0; - if (yValue< A.yValue) - return 1; - } - return 0; - } - - /** - Operator> takes xValue to last precidence. - Uses operator< to obtain value. - Note it does not uses 1-(A A - */ - int LocatedDataValue::operator>(const LocatedDataValue& A) const - { - return !(this->operator<(A)); - } - - /** Const accessor for X2 - @return The value of X2 - */ - const double& LocatedDataValue::X2() const - { - if (isHistogram()) - { - return x2Value; - } - else - { - throw Kernel::Exception::NotFoundError("X2 value is not set, check isHistogram() before accessing X2","X2"); - } - } - - /** Accessor for X2 - @return The value of X2 - */ - double& LocatedDataValue::X2() - { - if (isHistogram()) - { - return x2Value; - } - else - { - throw Kernel::Exception::NotFoundError("X2 value is not set, check isHistogram() before accessing X2","X2"); - } - } - - /** Const Accessor for X value - @return The X value - */ - const double& LocatedDataValue::X() const - { - return xValue; - } - - /** Accessor for X value - @return The X value - */ - double& LocatedDataValue::X() - { - return xValue; - } - - /** Const Accessor for Y value - @return The Y value - */ - const double& LocatedDataValue::Y() const - { - return yValue; - } - - /** Accessor for Y value - @return The Y value - */ - double& LocatedDataValue::Y() - { - return yValue; - } - - /** Const Accessor for E value - @return The E value - */ - const double& LocatedDataValue::E() const - { - return eValue; - } - - /** Accessor for E value - @return The E value - */ - double& LocatedDataValue::E() - { - return eValue; - } - - bool LocatedDataValue::isHistogram() const - { - return _isHistogram; - } - - - } // NAMESPACE API - -} // NAMESPACE Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/ManagedRawFileWorkspace2D.cpp b/Code/Mantid/Framework/DataHandling/src/ManagedRawFileWorkspace2D.cpp index b628b103b512..616cf12fd40e 100644 --- a/Code/Mantid/Framework/DataHandling/src/ManagedRawFileWorkspace2D.cpp +++ b/Code/Mantid/Framework/DataHandling/src/ManagedRawFileWorkspace2D.cpp @@ -1,9 +1,6 @@ #include "MantidDataHandling/ManagedRawFileWorkspace2D.h" #include "MantidKernel/Exception.h" #include "MantidAPI/RefAxis.h" -#include "MantidAPI/LocatedDataRef.h" -#include "MantidAPI/WorkspaceIterator.h" -#include "MantidAPI/WorkspaceIteratorCode.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/UnitFactory.h" diff --git a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp index f5e476f15f4e..3723b5f602ba 100644 --- a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp +++ b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp @@ -1,6 +1,5 @@ #include "MantidAPI/RefAxis.h" #include "MantidAPI/SpectraAxis.h" -#include "MantidAPI/LocatedDataRef.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/Progress.h" #include "MantidAPI/WorkspaceProperty.h" diff --git a/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp b/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp index 71ff7479c046..618090214a8b 100644 --- a/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp +++ b/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp @@ -2,9 +2,6 @@ #include "MantidKernel/Exception.h" #include "MantidAPI/RefAxis.h" #include "MantidAPI/SpectraAxis.h" -#include "MantidAPI/LocatedDataRef.h" -#include "MantidAPI/WorkspaceIterator.h" -#include "MantidAPI/WorkspaceIteratorCode.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/ISpectrum.h" @@ -178,9 +175,6 @@ namespace Mantid ///\cond TEMPLATE -template DLLExport class Mantid::API::workspace_iterator; -template DLLExport class Mantid::API::workspace_iterator; - template DLLExport class Mantid::API::WorkspaceProperty; namespace Mantid diff --git a/Code/Mantid/Framework/DataObjects/src/WorkspaceSingleValue.cpp b/Code/Mantid/Framework/DataObjects/src/WorkspaceSingleValue.cpp index 41ead4e8655b..022c07fbdd78 100644 --- a/Code/Mantid/Framework/DataObjects/src/WorkspaceSingleValue.cpp +++ b/Code/Mantid/Framework/DataObjects/src/WorkspaceSingleValue.cpp @@ -1,7 +1,4 @@ #include "MantidDataObjects/WorkspaceSingleValue.h" -#include "MantidAPI/LocatedDataRef.h" -#include "MantidAPI/WorkspaceIterator.h" -#include "MantidAPI/WorkspaceIteratorCode.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceFactory.h" @@ -73,8 +70,6 @@ namespace Mantid } // namespace Mantid ///\cond TEMPLATE -template DLLExport class Mantid::API::workspace_iterator; -template DLLExport class Mantid::API::workspace_iterator; template DLLExport class Mantid::API::WorkspaceProperty; From 8b4d456e6df47b8c48e3c07e5b91974a4edfc6d6 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 10 Feb 2014 22:04:09 +0000 Subject: [PATCH 057/118] Remove WorkspaceIteratorCodeTest Refs #8983 --- Code/Mantid/Framework/DataObjects/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Mantid/Framework/DataObjects/CMakeLists.txt b/Code/Mantid/Framework/DataObjects/CMakeLists.txt index eab9aa0810c4..4476049c0556 100644 --- a/Code/Mantid/Framework/DataObjects/CMakeLists.txt +++ b/Code/Mantid/Framework/DataObjects/CMakeLists.txt @@ -92,7 +92,6 @@ set ( TEST_FILES WeightedEventNoTimeTest.h WeightedEventTest.h Workspace2DTest.h - WorkspaceIteratorTest.h WorkspaceSingleValueTest.h WorkspaceValidatorsTest.h ) From 41d43a04e54ee3f0eb80501bf35ea75ea2a3c027 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 11 Feb 2014 10:06:23 +0000 Subject: [PATCH 058/118] Remove WorkspaceIterator usage in tests. Refs #8983 --- .../Algorithms/test/BinaryOperationTest.h | 1 - .../test/CommutativeBinaryOperationTest.h | 17 - .../test/ConvertAxisByFormulaTest.h | 366 +++++++++--------- .../Algorithms/test/ConvertUnitsTest.h | 9 +- .../Algorithms/test/CropWorkspaceTest.h | 49 ++- .../Framework/Algorithms/test/MergeRunsTest.h | 20 +- .../Framework/Algorithms/test/ScaleTest.h | 65 ++-- .../Framework/Algorithms/test/ScaleXTest.h | 71 ++-- .../Algorithms/test/StripPeaksTest.h | 24 +- 9 files changed, 320 insertions(+), 302 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/test/BinaryOperationTest.h b/Code/Mantid/Framework/Algorithms/test/BinaryOperationTest.h index 7e445250059e..67a1efa8899c 100644 --- a/Code/Mantid/Framework/Algorithms/test/BinaryOperationTest.h +++ b/Code/Mantid/Framework/Algorithms/test/BinaryOperationTest.h @@ -8,7 +8,6 @@ #include "MantidAlgorithms/BinaryOperation.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/WorkspaceIterator.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/Timer.h" diff --git a/Code/Mantid/Framework/Algorithms/test/CommutativeBinaryOperationTest.h b/Code/Mantid/Framework/Algorithms/test/CommutativeBinaryOperationTest.h index 824fdcbe6217..c50ae77e94bf 100644 --- a/Code/Mantid/Framework/Algorithms/test/CommutativeBinaryOperationTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CommutativeBinaryOperationTest.h @@ -126,23 +126,6 @@ class CommutativeBinaryOperationTest : public CxxTest::TestSuite TS_ASSERT(helper.checkSizeCompatibility(work_in1,work_event2).empty()); } - void checkOutputWorkspace(MatrixWorkspace_sptr ws, MatrixWorkspace_sptr wsIn1,MatrixWorkspace_sptr wsIn2 ) const - { - size_t targetsize = (wsIn1->size()>wsIn2->size())?wsIn1->size():wsIn2->size(); - TS_ASSERT_EQUALS(ws->size(),targetsize); - //check they are all 0 - for(MatrixWorkspace::iterator ti(*ws); ti != ti.end(); ++ti) - { - TS_ASSERT_THROWS_NOTHING - ( - LocatedDataRef tr = *ti; - TS_ASSERT_DELTA(tr.X(),0,0.0001); - TS_ASSERT_DELTA(tr.Y(),0,0.0001); - TS_ASSERT_DELTA(tr.E(),0,0.0001); - ) - } - } - }; #endif /*COMMUTATIVEBINARYOPERATIONTEST_H_*/ diff --git a/Code/Mantid/Framework/Algorithms/test/ConvertAxisByFormulaTest.h b/Code/Mantid/Framework/Algorithms/test/ConvertAxisByFormulaTest.h index b5db80367ac2..ee9cb523f1cf 100644 --- a/Code/Mantid/Framework/Algorithms/test/ConvertAxisByFormulaTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ConvertAxisByFormulaTest.h @@ -11,185 +11,195 @@ using Mantid::Algorithms::ConvertAxisByFormula; class ConvertAxisByFormulaTest : public CxxTest::TestSuite { public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static ConvertAxisByFormulaTest *createSuite() { return new ConvertAxisByFormulaTest(); } - static void destroySuite( ConvertAxisByFormulaTest *suite ) { delete suite; } - - void testPlusRefAxis() - { - using namespace Mantid::API; - using namespace Mantid::Kernel; - - Mantid::Algorithms::ConvertAxisByFormula alg; - alg.initialize(); - - std::string inputWs= alg.name() + "_testPlusRefAxis_Input"; - std::string resultWs= alg.name() + "_testPlusRefAxis_Result"; - - AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::Create2DWorkspace123(10,10)); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","x+3") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","My Title") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","MyUnit") ) - - TS_ASSERT_THROWS_NOTHING( alg.execute() ) - TS_ASSERT( alg.isExecuted() ) - - if (!alg.isExecuted()) - { - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - return; - } - - MatrixWorkspace_const_sptr in,result; - TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(inputWs)) ) - TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(resultWs)) ) - - Axis* ax= result->getAxis(0); - TS_ASSERT_EQUALS(ax->unit()->caption(), "My Title"); - TS_ASSERT_EQUALS(ax->unit()->label(), "MyUnit"); - MatrixWorkspace::const_iterator inIt(*in); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), inIt->X()+3 ) - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ) - TS_ASSERT_EQUALS( it->E(), inIt->E() ) - } - - - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - if (AnalysisDataService::Instance().doesExist(resultWs)) - { - AnalysisDataService::Instance().remove(resultWs); - } - - - } - - void testSquareXNumericAxis() - { - using namespace Mantid::API; - using namespace Mantid::Kernel; - - Mantid::Algorithms::ConvertAxisByFormula alg; - alg.initialize(); - - std::string inputWs= alg.name() + "_testSquareXNumeric_Input"; - std::string resultWs= alg.name() + "_testSquareXNumeric_Result"; - - AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::Create2DWorkspace123(10,10)); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","(X+2)*(x+2)") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","XTitle") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","XUnit") ) - - TS_ASSERT_THROWS_NOTHING( alg.execute() ) - TS_ASSERT( alg.isExecuted() ) - - if (!alg.isExecuted()) - { - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - return; - } - - MatrixWorkspace_const_sptr in,result; - TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(inputWs)) ) - TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(resultWs)) ) - - Axis* ax= result->getAxis(0); - TS_ASSERT_EQUALS(ax->unit()->caption(), "XTitle"); - TS_ASSERT_EQUALS(ax->unit()->label(), "XUnit"); - for (size_t i = 0;ilength();++i) - { - TS_ASSERT_DELTA(ax->getValue(i),9.0,0.0001); - } - - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - if (AnalysisDataService::Instance().doesExist(resultWs)) - { - AnalysisDataService::Instance().remove(resultWs); - } - } - - - void testSquareYNumericAxisDefaultUnits() - { - using namespace Mantid::API; - using namespace Mantid::Kernel; - - Mantid::Algorithms::ConvertAxisByFormula alg; - alg.initialize(); - - std::string inputWs= alg.name() + "_testSquareXNumeric_Input"; - std::string resultWs= alg.name() + "_testSquareXNumeric_Result"; - - AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::create2DWorkspaceThetaVsTOF(10,10)); - - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","(y+2)*(Y+2)") ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","Y") ) - - TS_ASSERT_THROWS_NOTHING( alg.execute() ) - TS_ASSERT( alg.isExecuted() ) - - if (!alg.isExecuted()) - { - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - return; - } - - MatrixWorkspace_const_sptr in,result; - TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(inputWs)) ) - TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve(resultWs)) ) - - Axis* ax= result->getAxis(1); - TS_ASSERT_EQUALS(ax->unit()->caption(),in->getAxis(1)->unit()->caption()); - TS_ASSERT_EQUALS(ax->unit()->label(), in->getAxis(1)->unit()->label()); - for (size_t i = 0;ilength();++i) - { - TS_ASSERT_DELTA(ax->getValue(i),(i+1+2)*(i+1+2),0.0001); - } - - if (AnalysisDataService::Instance().doesExist(inputWs)) - { - AnalysisDataService::Instance().remove(inputWs); - } - if (AnalysisDataService::Instance().doesExist(resultWs)) - { - AnalysisDataService::Instance().remove(resultWs); - } - - - } + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static ConvertAxisByFormulaTest *createSuite() { return new ConvertAxisByFormulaTest(); } + static void destroySuite( ConvertAxisByFormulaTest *suite ) { delete suite; } + + void testPlusRefAxis() + { + using namespace Mantid::API; + using namespace Mantid::Kernel; + + Mantid::Algorithms::ConvertAxisByFormula alg; + alg.initialize(); + + std::string inputWs= alg.name() + "_testPlusRefAxis_Input"; + std::string resultWs= alg.name() + "_testPlusRefAxis_Result"; + + AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::Create2DWorkspace123(10,10)); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","x+3") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","My Title") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","MyUnit") ) + + TS_ASSERT_THROWS_NOTHING( alg.execute() ) + TS_ASSERT( alg.isExecuted() ) + + if (!alg.isExecuted()) + { + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + return; + } + + MatrixWorkspace_const_sptr in,result; + TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(inputWs)) ) + TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(resultWs)) ) + + Axis* ax= result->getAxis(0); + TS_ASSERT_EQUALS(ax->unit()->caption(), "My Title"); + TS_ASSERT_EQUALS(ax->unit()->label(), "MyUnit"); + const size_t xsize = result->blocksize(); + for(size_t i = 0; i < result->getNumberHistograms(); ++i) + { + const auto & outX = result->readX(i); + const auto & outY = result->readY(i); + const auto & outE = result->readE(i); + const auto & inX = in->readX(i); + const auto & inY = in->readY(i); + const auto & inE = in->readE(i); + + for(size_t j = 0; j < xsize; ++j) + { + TS_ASSERT_EQUALS(outX[j], inX[j] + 3); + TS_ASSERT_EQUALS(outY[j], inY[j]); + TS_ASSERT_EQUALS(outE[j], inE[j]); + } + } + + + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + if (AnalysisDataService::Instance().doesExist(resultWs)) + { + AnalysisDataService::Instance().remove(resultWs); + } + + + } + + void testSquareXNumericAxis() + { + using namespace Mantid::API; + using namespace Mantid::Kernel; + + Mantid::Algorithms::ConvertAxisByFormula alg; + alg.initialize(); + + std::string inputWs= alg.name() + "_testSquareXNumeric_Input"; + std::string resultWs= alg.name() + "_testSquareXNumeric_Result"; + + AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::Create2DWorkspace123(10,10)); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","(X+2)*(x+2)") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","XTitle") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","XUnit") ) + + TS_ASSERT_THROWS_NOTHING( alg.execute() ) + TS_ASSERT( alg.isExecuted() ) + + if (!alg.isExecuted()) + { + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + return; + } + + MatrixWorkspace_const_sptr in,result; + TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(inputWs)) ) + TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(resultWs)) ) + + Axis* ax= result->getAxis(0); + TS_ASSERT_EQUALS(ax->unit()->caption(), "XTitle"); + TS_ASSERT_EQUALS(ax->unit()->label(), "XUnit"); + for (size_t i = 0;ilength();++i) + { + TS_ASSERT_DELTA(ax->getValue(i),9.0,0.0001); + } + + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + if (AnalysisDataService::Instance().doesExist(resultWs)) + { + AnalysisDataService::Instance().remove(resultWs); + } + } + + + void testSquareYNumericAxisDefaultUnits() + { + using namespace Mantid::API; + using namespace Mantid::Kernel; + + Mantid::Algorithms::ConvertAxisByFormula alg; + alg.initialize(); + + std::string inputWs= alg.name() + "_testSquareXNumeric_Input"; + std::string resultWs= alg.name() + "_testSquareXNumeric_Result"; + + AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::create2DWorkspaceThetaVsTOF(10,10)); + + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","(y+2)*(Y+2)") ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","Y") ) + + TS_ASSERT_THROWS_NOTHING( alg.execute() ) + TS_ASSERT( alg.isExecuted() ) + + if (!alg.isExecuted()) + { + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + return; + } + + MatrixWorkspace_const_sptr in,result; + TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(inputWs)) ) + TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve(resultWs)) ) + + Axis* ax= result->getAxis(1); + TS_ASSERT_EQUALS(ax->unit()->caption(),in->getAxis(1)->unit()->caption()); + TS_ASSERT_EQUALS(ax->unit()->label(), in->getAxis(1)->unit()->label()); + for (size_t i = 0;ilength();++i) + { + TS_ASSERT_DELTA(ax->getValue(i),(i+1+2)*(i+1+2),0.0001); + } + + if (AnalysisDataService::Instance().doesExist(inputWs)) + { + AnalysisDataService::Instance().remove(inputWs); + } + if (AnalysisDataService::Instance().doesExist(resultWs)) + { + AnalysisDataService::Instance().remove(resultWs); + } + + + } }; -#endif /* MANTID_ALGORITHMS_CONVERTAXISBYFORMULATEST_H_ */ \ No newline at end of file +#endif /* MANTID_ALGORITHMS_CONVERTAXISBYFORMULATEST_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h b/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h index 0675158ddc0a..5eebc40b76cd 100644 --- a/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h @@ -220,9 +220,14 @@ class ConvertUnitsTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS("quickOut") ); TS_ASSERT_EQUALS( output->getAxis(0)->unit()->unitID(), "dSpacing"); TS_ASSERT_EQUALS( &(output->dataX(0)[0]), &(output->dataX(0)[0]) ); - for (MatrixWorkspace::const_iterator it(*output); it != it.end(); ++it) + const size_t xsize = output->blocksize(); + for(size_t i = 0; i < output->getNumberHistograms(); ++i) { - TS_ASSERT_EQUALS( it->X(), 2.0*M_PI ); + const auto & outX = output->readX(i); + for(size_t j = 0; j <= xsize; ++j) + { + TS_ASSERT_EQUALS( outX[j], 2.0*M_PI ); + } } AnalysisDataService::Instance().remove("quickIn"); diff --git a/Code/Mantid/Framework/Algorithms/test/CropWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/CropWorkspaceTest.h index d1da78c91e61..3f75fd14f9fc 100644 --- a/Code/Mantid/Framework/Algorithms/test/CropWorkspaceTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CropWorkspaceTest.h @@ -5,13 +5,10 @@ #include "MantidAPI/TextAxis.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/cow_ptr.h" -#include "MantidKernel/System.h" #include "MantidKernel/Timer.h" #include "MantidKernel/UnitFactory.h" #include "MantidTestHelpers/ComponentCreationHelper.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" -#include "MantidTestHelpers/WorkspaceCreationHelper.h" #include #include @@ -197,14 +194,25 @@ class CropWorkspaceTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS("unCropped") ); MatrixWorkspace_const_sptr input = AnalysisDataService::Instance().retrieveWS("toCrop"); - MatrixWorkspace::const_iterator inIt(*input); - for (MatrixWorkspace::const_iterator it(*output); it != it.end(); ++it,++inIt) + const size_t xsize = output->blocksize(); + for(size_t i = 0; i < output->getNumberHistograms(); ++i) { - TS_ASSERT_EQUALS( it->X(), inIt->X() ); - TS_ASSERT_EQUALS( it->X2(), inIt->X2() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); + const auto & outX = output->readX(i); + const auto & outY = output->readY(i); + const auto & outE = output->readE(i); + const auto & inX = input->readX(i); + const auto & inY = input->readY(i); + const auto & inE = input->readE(i); + + for(size_t j = 0; j < xsize; ++j) + { + TS_ASSERT_EQUALS(outX[j], inX[j]); + TS_ASSERT_EQUALS(outY[j], inY[j]); + TS_ASSERT_EQUALS(outE[j], inE[j]); + } + TS_ASSERT_EQUALS(outX[xsize], inX[xsize]); } + for (int i = 0; i < 5; ++i) { TS_ASSERT_EQUALS( output->getAxis(1)->spectraNo(i), input->getAxis(1)->spectraNo(i) ); @@ -226,14 +234,25 @@ class CropWorkspaceTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS("pointOut") ); MatrixWorkspace_const_sptr input = AnalysisDataService::Instance().retrieveWS("point"); - MatrixWorkspace::const_iterator inIt(*input); - for (MatrixWorkspace::const_iterator it(*output); it != it.end(); ++it,++inIt) + const size_t xsize = output->blocksize(); + for(size_t i = 0; i < output->getNumberHistograms(); ++i) { - TS_ASSERT_EQUALS( it->X(), inIt->X() ); - TS_ASSERT_THROWS( it->X2(), Mantid::Kernel::Exception::NotFoundError ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); + const auto & outX = output->readX(i); + const auto & outY = output->readY(i); + const auto & outE = output->readE(i); + const auto & inX = input->readX(i); + const auto & inY = input->readY(i); + const auto & inE = input->readE(i); + + for(size_t j = 0; j < xsize; ++j) + { + TS_ASSERT_EQUALS(outX[j], inX[j]); + TS_ASSERT_EQUALS(outY[j], inY[j]); + TS_ASSERT_EQUALS(outE[j], inE[j]); + } } + + AnalysisDataService::Instance().remove("point"); AnalysisDataService::Instance().remove("pointOut"); } diff --git a/Code/Mantid/Framework/Algorithms/test/MergeRunsTest.h b/Code/Mantid/Framework/Algorithms/test/MergeRunsTest.h index 73b38cc96ad5..2142b525716b 100644 --- a/Code/Mantid/Framework/Algorithms/test/MergeRunsTest.h +++ b/Code/Mantid/Framework/Algorithms/test/MergeRunsTest.h @@ -314,13 +314,23 @@ class MergeRunsTest : public CxxTest::TestSuite MatrixWorkspace_const_sptr output; TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS("outWS") ); + MatrixWorkspace_const_sptr input = AnalysisDataService::Instance().retrieveWS("in1"); - MatrixWorkspace::const_iterator inIt(*(AnalysisDataService::Instance().retrieveWS("in1"))); - for (MatrixWorkspace::const_iterator it(*output); it != it.end(); ++it,++inIt) + TS_ASSERT_EQUALS(input->getNumberHistograms(), output->getNumberHistograms()); + TS_ASSERT_EQUALS(input->blocksize(), output->blocksize()); + + const size_t xsize = output->blocksize(); + for(size_t i = 0; i < output->getNumberHistograms(); ++i) { - TS_ASSERT_EQUALS( it->X(), inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), 6.0 ); - TS_ASSERT_DELTA( it->E(), sqrt(6.0), 0.00001 ); + const auto & outX = output->readX(i); + const auto & outY = output->readY(i); + const auto & outE = output->readE(i); + for(size_t j = 0; j < xsize; ++j) + { + TS_ASSERT_DELTA(outX[j], input->readX(i)[j], 1e-12); + TS_ASSERT_DELTA(outY[j], 6.0, 1e-12); + TS_ASSERT_DELTA(outE[j], sqrt(6.0), 1e-5); + } } AnalysisDataService::Instance().remove("outWS"); diff --git a/Code/Mantid/Framework/Algorithms/test/ScaleTest.h b/Code/Mantid/Framework/Algorithms/test/ScaleTest.h index 70e6eadb995c..cfea88bb3c79 100644 --- a/Code/Mantid/Framework/Algorithms/test/ScaleTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ScaleTest.h @@ -34,26 +34,20 @@ class ScaleTest : public CxxTest::TestSuite if (!scale.isInitialized()) scale.initialize(); AnalysisDataService::Instance().add("tomultiply",WorkspaceCreationHelper::Create2DWorkspace123(10,10)); - TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("InputWorkspace","tomultiply") ) - TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("OutputWorkspace","multiplied") ) - TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("Factor","2.5") ) + TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("InputWorkspace","tomultiply") ); + TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("OutputWorkspace","multiplied") ); + TS_ASSERT_THROWS_NOTHING( scale.setPropertyValue("Factor","2.5") ); - TS_ASSERT_THROWS_NOTHING( scale.execute() ) - TS_ASSERT( scale.isExecuted() ) + TS_ASSERT_THROWS_NOTHING( scale.execute() ); + TS_ASSERT( scale.isExecuted() ); MatrixWorkspace_const_sptr in,result; TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve("tomultiply")) ) + (AnalysisDataService::Instance().retrieve("tomultiply")) ); TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve("multiplied")) ) + (AnalysisDataService::Instance().retrieve("multiplied")) ); - MatrixWorkspace::const_iterator inIt(*in); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), inIt->X() ) - TS_ASSERT_EQUALS( it->Y(), 2.5*inIt->Y() ) - TS_ASSERT_EQUALS( it->E(), 2.5*inIt->E() ) - } + testScaleFactorApplied(in, result, 2.5, true); //multiply=true AnalysisDataService::Instance().remove("tomultiply"); AnalysisDataService::Instance().remove("multiplied"); @@ -68,33 +62,46 @@ class ScaleTest : public CxxTest::TestSuite scale2.initialize(); AnalysisDataService::Instance().add("toadd",WorkspaceCreationHelper::Create2DWorkspace123(10,10)); - TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("InputWorkspace","toadd") ) - TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("OutputWorkspace","added") ) - TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("Factor","-100.0") ) - TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("Operation","Add") ) + TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("InputWorkspace","toadd") ); + TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("OutputWorkspace","added") ); + TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("Factor","-100.0") ); + TS_ASSERT_THROWS_NOTHING( scale2.setPropertyValue("Operation","Add") ); - TS_ASSERT_THROWS_NOTHING( scale2.execute() ) - TS_ASSERT( scale2.isExecuted() ) + TS_ASSERT_THROWS_NOTHING( scale2.execute() ); + TS_ASSERT( scale2.isExecuted() ); MatrixWorkspace_const_sptr in,result; TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve("toadd")) ) + (AnalysisDataService::Instance().retrieve("toadd")) ); TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast - (AnalysisDataService::Instance().retrieve("added")) ) + (AnalysisDataService::Instance().retrieve("added")) ); - MatrixWorkspace::const_iterator inIt(*in); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), inIt->X() ) - TS_ASSERT_EQUALS( it->Y(), inIt->Y()-100.0 ) - TS_ASSERT_EQUALS( it->E(), inIt->E() ) - } + testScaleFactorApplied(in, result, -100, false); //multiply=false AnalysisDataService::Instance().remove("toadd"); AnalysisDataService::Instance().remove("added"); } private: + void testScaleFactorApplied(const Mantid::API::MatrixWorkspace_const_sptr & inputWS, + const Mantid::API::MatrixWorkspace_const_sptr & outputWS, + double factor, bool multiply) + { + const size_t xsize = outputWS->blocksize(); + for(size_t i = 0; i < outputWS->getNumberHistograms(); ++i) + { + for(size_t j = 0; j < xsize; ++j) + { + TS_ASSERT_DELTA(outputWS->readX(i)[j], inputWS->readX(i)[j], 1e-12); + double resultY = (multiply) ? factor*inputWS->readY(i)[j] : factor + inputWS->readY(i)[j]; + TS_ASSERT_DELTA(outputWS->readY(i)[j], resultY, 1e-12); + double resultE = (multiply) ? factor*inputWS->readE(i)[j] : factor + inputWS->readE(i)[j]; + TS_ASSERT_DELTA(outputWS->readE(i)[j], resultE, 1e-12); + } + } + } + + Mantid::Algorithms::Scale scale; }; diff --git a/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h b/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h index 36c608157ccb..d5df88c8a6bf 100755 --- a/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h @@ -37,14 +37,7 @@ class ScaleXTest : public CxxTest::TestSuite auto inputWS = WorkspaceCreationHelper::Create2DWorkspace123(10,10); double factor = 2.5; auto result = runScaleX(inputWS, "Multiply", factor); - - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 2.5*inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } + testScaleFactorApplied(inputWS, result, factor, true); //multiply=true } void testAddOnWS2D() @@ -55,14 +48,8 @@ class ScaleXTest : public CxxTest::TestSuite auto inputWS = WorkspaceCreationHelper::Create2DWorkspace123(10,10); double factor = 2.5; auto result = runScaleX(inputWS, "Add", factor); + testScaleFactorApplied(inputWS, result, factor, false); //multiply=false - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 2.5 + inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } } void testMulitplyOnEvents() @@ -76,16 +63,8 @@ class ScaleXTest : public CxxTest::TestSuite auto inputWS = WorkspaceCreationHelper::CreateEventWorkspace2(10,10); double factor(2.5); auto result = runScaleX(inputWS, "Multiply", factor); - TS_ASSERT_EQUALS("EventWorkspace", result->id()); - - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 2.5*inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } + testScaleFactorApplied(inputWS, result, factor, true); //multiply=true } void testAddOnEvents() @@ -99,16 +78,9 @@ class ScaleXTest : public CxxTest::TestSuite auto inputWS = WorkspaceCreationHelper::CreateEventWorkspace2(10,10); double factor(2.5); auto result = runScaleX(inputWS, "Add", factor); - TS_ASSERT_EQUALS("EventWorkspace", result->id()); + testScaleFactorApplied(inputWS, result, factor, false); //multiply=false - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 2.5 + inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } } @@ -215,14 +187,7 @@ class ScaleXTest : public CxxTest::TestSuite double algFactor(2.0); bool combine(true); auto result = runScaleX(inputWS, "Multiply", algFactor, parname, combine); - - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 20.0*inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } + testScaleFactorApplied(inputWS, result, algFactor*instFactor, true); //multiply=true } @@ -241,15 +206,7 @@ class ScaleXTest : public CxxTest::TestSuite double algFactor(2.0); bool combine(true); auto result = runScaleX(inputWS, "Add", algFactor, parname, combine); - - MatrixWorkspace::const_iterator inIt(*inputWS); - for (MatrixWorkspace::const_iterator it(*result); it != it.end(); ++it,++inIt) - { - TS_ASSERT_EQUALS( it->X(), 12.0 + inIt->X() ); - TS_ASSERT_EQUALS( it->Y(), inIt->Y() ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); - } - + testScaleFactorApplied(inputWS, result, algFactor*instFactor, false); //multiply=true } @@ -322,6 +279,22 @@ class ScaleXTest : public CxxTest::TestSuite return scale.getProperty("OutputWorkspace"); } + void testScaleFactorApplied(const Mantid::API::MatrixWorkspace_const_sptr & inputWS, + const Mantid::API::MatrixWorkspace_const_sptr & outputWS, + double factor, bool multiply) + { + const size_t xsize = outputWS->blocksize(); + for(size_t i = 0; i < outputWS->getNumberHistograms(); ++i) + { + for(size_t j = 0; j < xsize; ++j) + { + double resultX = (multiply) ? factor*inputWS->readX(i)[j] : factor + inputWS->readX(i)[j]; + TS_ASSERT_DELTA(outputWS->readX(i)[j], resultX, 1e-12); + TS_ASSERT_EQUALS(outputWS->readY(i)[j], inputWS->readY(i)[j]); + TS_ASSERT_EQUALS(outputWS->readE(i)[j], inputWS->readE(i)[j]); + } + } + } }; #endif /*SCALEXTEST_H_*/ diff --git a/Code/Mantid/Framework/Algorithms/test/StripPeaksTest.h b/Code/Mantid/Framework/Algorithms/test/StripPeaksTest.h index 164842607579..89e227c7dc0d 100644 --- a/Code/Mantid/Framework/Algorithms/test/StripPeaksTest.h +++ b/Code/Mantid/Framework/Algorithms/test/StripPeaksTest.h @@ -53,7 +53,7 @@ class StripPeaksTest : public CxxTest::TestSuite TS_ASSERT( strip.isInitialized() ); } - void xtestExec() + void testExec() { if ( !strip.isInitialized() ) strip.initialize(); @@ -70,13 +70,25 @@ class StripPeaksTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS(outputWS) ); MatrixWorkspace_const_sptr input = AnalysisDataService::Instance().retrieveWS("toStrip"); - MatrixWorkspace::const_iterator inIt(*input); - for (MatrixWorkspace::const_iterator it(*output); it != it.end(); ++it,++inIt) + const size_t nhist = output->getNumberHistograms(); + const size_t nbins = output->blocksize(); + TS_ASSERT_EQUALS(nhist, input->getNumberHistograms()); + TS_ASSERT_EQUALS(nbins, input->blocksize()); + + for(size_t i = 0; i < nhist; ++i) { - TS_ASSERT_EQUALS( it->X(), inIt->X() ); - TS_ASSERT_DELTA( it->Y(), 5000.0, 0.5 ); - TS_ASSERT_EQUALS( it->E(), inIt->E() ); + const auto & inX = input->readX(i); + const auto & inE = input->readE(i); + const auto & outX = output->readX(i); + const auto & outY = output->readY(i); + const auto & outE = output->readE(i); + for(size_t j = 0; j < nbins; ++j) + { + TS_ASSERT_EQUALS( outX[j], inX[j] ); + TS_ASSERT_DELTA( outY[j], 5000.0, 0.5 ); + TS_ASSERT_EQUALS( outE[j], inE[j] ); + } } AnalysisDataService::Instance().remove(outputWS); From f4307dd8823afe916a0544fa5c90516a79a38f99 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 3 Mar 2014 10:03:04 +0000 Subject: [PATCH 059/118] Fix broken Scale*Tests Refs #8983 --- Code/Mantid/Framework/Algorithms/test/ScaleTest.h | 2 +- Code/Mantid/Framework/Algorithms/test/ScaleXTest.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/test/ScaleTest.h b/Code/Mantid/Framework/Algorithms/test/ScaleTest.h index cfea88bb3c79..181c5819810a 100644 --- a/Code/Mantid/Framework/Algorithms/test/ScaleTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ScaleTest.h @@ -95,7 +95,7 @@ class ScaleTest : public CxxTest::TestSuite TS_ASSERT_DELTA(outputWS->readX(i)[j], inputWS->readX(i)[j], 1e-12); double resultY = (multiply) ? factor*inputWS->readY(i)[j] : factor + inputWS->readY(i)[j]; TS_ASSERT_DELTA(outputWS->readY(i)[j], resultY, 1e-12); - double resultE = (multiply) ? factor*inputWS->readE(i)[j] : factor + inputWS->readE(i)[j]; + double resultE = (multiply) ? factor*inputWS->readE(i)[j] : inputWS->readE(i)[j]; TS_ASSERT_DELTA(outputWS->readE(i)[j], resultE, 1e-12); } } diff --git a/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h b/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h index d5df88c8a6bf..6461f92f02f6 100755 --- a/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ScaleXTest.h @@ -206,7 +206,7 @@ class ScaleXTest : public CxxTest::TestSuite double algFactor(2.0); bool combine(true); auto result = runScaleX(inputWS, "Add", algFactor, parname, combine); - testScaleFactorApplied(inputWS, result, algFactor*instFactor, false); //multiply=true + testScaleFactorApplied(inputWS, result, algFactor+instFactor, false); //multiply=true } From e33309e8189f44100d28dbb3fbf3f6c363a907c8 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Mon, 3 Mar 2014 10:06:46 +0000 Subject: [PATCH 060/118] Refs #9058. Name variable better. --- Code/Mantid/MantidPlot/src/Graph.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/Graph.cpp b/Code/Mantid/MantidPlot/src/Graph.cpp index ee14b462a104..0925bc4f7ba5 100644 --- a/Code/Mantid/MantidPlot/src/Graph.cpp +++ b/Code/Mantid/MantidPlot/src/Graph.cpp @@ -3217,7 +3217,7 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid if (xColName.isEmpty() || yColName.isEmpty()) return false; - PlotCurve* c(NULL); + PlotCurve* newCurve(NULL); // --- Drawing error columns ----------------------------- if (colType == Table::xErr || colType == Table::yErr){ @@ -3227,7 +3227,7 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid else dir = QwtErrorPlotCurve::Vertical; - c = addErrorBars(xColName, yColName, w, colName, dir); + newCurve = addErrorBars(xColName, yColName, w, colName, dir); // --- Drawing label columns ----------------------------- } else if (colType == Table::Label){ DataCurve* mc = masterCurve(xColName, yColName); @@ -3239,17 +3239,17 @@ bool Graph::addCurves(Table* w, const QStringList& names, int style, double lWid // --- Drawing Y columns ----------------------------- } else if (colType == Table::Y) { - c = insertCurve(w, xColName, yColName, style, startRow, endRow); + newCurve = insertCurve(w, xColName, yColName, style, startRow, endRow); } // Set a layout for the new curve, if we've added one - if (c) + if (newCurve) { CurveLayout cl = initCurveLayout(style, drawableNames.count() - noOfErrorCols); cl.sSize = sSize; cl.lWidth = static_cast(lWidth); - updateCurveLayout(c, &cl); + updateCurveLayout(newCurve, &cl); } } } From 198e7dc07054676e7e5a271e6f2e345e37e87ab7 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 3 Mar 2014 10:07:51 +0000 Subject: [PATCH 061/118] Export base IPropertySettings class to Python. Refs #8947 --- .../mantid/kernel/CMakeLists.txt | 1 + .../kernel/src/Exports/IPropertySettings.cpp | 18 ++++++++++++++++++ .../test/python/mantid/kernel/CMakeLists.txt | 1 + .../mantid/kernel/IPropertySettingsTest.py | 14 ++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/IPropertySettingsTest.py diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index ad835d5b5a03..a41337feb4e7 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -13,6 +13,7 @@ set ( EXPORT_FILES src/Exports/IPropertyManager.cpp src/Exports/Property.cpp src/Exports/IValidator.cpp + src/Exports/IPropertySettings.cpp src/Exports/PropertyWithValue.cpp src/Exports/ArrayProperty.cpp src/Exports/Quat.cpp diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp new file mode 100644 index 000000000000..685d7dd5af3b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp @@ -0,0 +1,18 @@ +#include "MantidKernel/IPropertySettings.h" +#include "MantidKernel/IPropertyManager.h" +#include + +using Mantid::Kernel::IPropertySettings; +using namespace boost::python; + +void export_IPropertySettings() +{ + class_("IPropertySettings", no_init) + .def("isEnabled", &IPropertySettings::isEnabled, + "Is the property to be shown as enabled in the GUI. Default true.") + + .def("isVisible", &IPropertySettings::isVisible, + "Is the property to be shown in the GUI? Default true.") + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt index 9478a378c87a..fb5ce86abee5 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt @@ -13,6 +13,7 @@ set ( TEST_PY_FILES FacilityInfoTest.py FilteredTimeSeriesPropertyTest.py InstrumentInfoTest.py + IPropertySettingsTest.py ListValidatorTest.py LogFilterTest.py LoggerTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/IPropertySettingsTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/IPropertySettingsTest.py new file mode 100644 index 000000000000..60a79bb46d53 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/IPropertySettingsTest.py @@ -0,0 +1,14 @@ +import unittest +from mantid.kernel import IPropertySettings + +class IPropertySettingsTest(unittest.TestCase): + + def test_construction_raises_an_exception(self): + self.assertRaises(RuntimeError, IPropertySettings) + + def test_interface_has_expected_attrs(self): + self.assertTrue(hasattr(IPropertySettings, "isEnabled")) + self.assertTrue(hasattr(IPropertySettings, "isVisible")) + +if __name__ == '__main__': + unittest.main() From 5d3b45078f27dd0ac8ee71390b56ed26861ae3ca Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 3 Mar 2014 11:11:17 +0000 Subject: [PATCH 062/118] Export EnabledWhenProperty to Python. Refs #8947 --- .../mantid/kernel/CMakeLists.txt | 1 + .../src/Exports/EnabledWhenProperty.cpp | 33 +++++++++++++++++++ .../test/python/mantid/kernel/CMakeLists.txt | 1 + .../mantid/kernel/EnabledWhenPropertyTest.py | 25 ++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/EnabledWhenProperty.cpp create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index a41337feb4e7..5fae99cafc22 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -14,6 +14,7 @@ set ( EXPORT_FILES src/Exports/Property.cpp src/Exports/IValidator.cpp src/Exports/IPropertySettings.cpp + src/Exports/EnabledWhenProperty.cpp src/Exports/PropertyWithValue.cpp src/Exports/ArrayProperty.cpp src/Exports/Quat.cpp diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/EnabledWhenProperty.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/EnabledWhenProperty.cpp new file mode 100644 index 000000000000..d2b8a15ee8e5 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/EnabledWhenProperty.cpp @@ -0,0 +1,33 @@ +#include "MantidKernel/EnabledWhenProperty.h" +#include +#include + +using namespace Mantid::Kernel; +using namespace boost::python; + +void export_EnabledWhenProperty() +{ + // State enumeration + enum_("PropertyCriterion") + .value("IsDefault", IS_DEFAULT) + .value("IsNotDefault", IS_NOT_DEFAULT) + .value("IsEqualTo", IS_EQUAL_TO) + .value("IsNotEqualTo", IS_NOT_EQUAL_TO) + .value("IsMoreOrEqual", IS_MORE_OR_EQ) + ; + + class_, + boost::noncopyable>("EnabledWhenProperty", no_init) // no default constructor + + .def(init( + (arg("otherPropName"), arg("when"), arg("value")), + "Enabled otherPropName property when value criterion meets that given by the 'when' argument") + ) + + .def(init( + (arg("otherPropName"), arg("when")), + "Enabled otherPropName property when criterion does not require a value, i.e isDefault") + ) + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt index fb5ce86abee5..c5fea345ad25 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt @@ -10,6 +10,7 @@ set ( TEST_PY_FILES ConfigServiceTest.py DateAndTimeTest.py DeltaEModeTest.py + EnabledWhenPropertyTest.py FacilityInfoTest.py FilteredTimeSeriesPropertyTest.py InstrumentInfoTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py new file mode 100644 index 000000000000..33da875bcaf3 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py @@ -0,0 +1,25 @@ +import unittest +from mantid.kernel import EnabledWhenProperty, PropertyCriterion + +class EnabledWhenPropertyTest(unittest.TestCase): + + def test_construction_with_name_criterion_only_succeeds(self): + p = EnabledWhenProperty("OtherProperty", PropertyCriterion.IsDefault) + + def test_construction_with_name_criterion_value_succeeds(self): + p = EnabledWhenProperty("OtherProperty", PropertyCriterion.IsEqualTo, "value") + + #------------ Failure cases ------------------ + + def test_default_construction_raises_error(self): + try: + EnabledWhenProperty() + self.fail("Expected default constructor to raise an error") + except Exception, e: + # boost.python.ArgumentError are not catchable + if "Python argument types in" not in str(e): + raise RuntimeError("Unexpected exception type raised") + + +if __name__ == '__main__': + unittest.main() From 8476aca0d7695a71e6a874702a9fa544d130a848 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 13:37:20 +0000 Subject: [PATCH 063/118] Add session property to catalog algorithms. Refs #9084. --- .../Framework/ICat/src/CatalogDownloadDataFiles.cpp | 7 +++++-- Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp | 3 ++- .../Mantid/Framework/ICat/src/CatalogListInstruments.cpp | 9 ++++----- .../Framework/ICat/src/CatalogListInvestigationTypes.cpp | 8 ++++---- Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp | 3 ++- Code/Mantid/Framework/ICat/src/CatalogPublish.cpp | 7 +++++-- Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 4 +++- 8 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp index 7483a648a098..10ea25ac0d8f 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp @@ -5,8 +5,9 @@ if the data archive is not accessible, it downloads the files from the data serv *WIKI*/ -#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/ICatalogInfoService.h" +#include "MantidAPI/WorkspaceProperty.h" #include "MantidICat/CatalogDownloadDataFiles.h" #include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidKernel/PropertyWithValue.h" @@ -55,13 +56,15 @@ namespace Mantid boost::make_shared(), Direction::Output), "A list of file locations to the catalog datafiles."); + declareProperty("Session","","The session information of the catalog to use."); } /// Execute the algorithm void CatalogDownloadDataFiles::exec() { // Cast a catalog to a catalogInfoService to access downloading functionality. - auto catalogInfoService = boost::dynamic_pointer_cast(CatalogAlgorithmHelper().createCatalog()); + auto catalogInfoService = boost::dynamic_pointer_cast( + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))); // Check if the catalog created supports publishing functionality. if (!catalogInfoService) throw std::runtime_error("The catalog that you are using does not support external downloading."); diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index 7917dc72deba..664ecffcc7a2 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -29,13 +29,14 @@ namespace Mantid "ID of the selected investigation"); declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the data file search details"); + declareProperty("Session","","The session information of the catalog to use."); } //execute the algorithm void CatalogGetDataFiles::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->getDataFiles(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))->getDataFiles(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 749fc7fb3836..6fc4b42aebee 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -28,13 +28,14 @@ namespace Mantid "ID of the selected investigation"); declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the result of datasets search "); + declareProperty("Session","","The session information of the catalog to use."); } /// exec methods void CatalogGetDataSets::exec() { auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->getDataSets(getProperty("InvestigationId"),workspace); + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))->getDataSets(getProperty("InvestigationId"),workspace); setProperty("OutputWorkspace",workspace); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 4699b254fe9b..6ef4be69a628 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -25,17 +25,16 @@ namespace Mantid /// Init method void CatalogListInstruments::init() { - declareProperty( new Kernel::ArrayProperty("InstrumentList",std::vector(), - boost::make_shared(), - Kernel::Direction::Output), - "A list containing instrument names"); + declareProperty(new Kernel::ArrayProperty("InstrumentList",std::vector(), + boost::make_shared(),Kernel::Direction::Output), "A list containing instrument names."); + declareProperty("Session","","The session information of the catalog to use."); } /// exec method void CatalogListInstruments::exec() { std::vector instruments; - API::CatalogManager::Instance().getCatalog("")->listInstruments(instruments); + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))->listInstruments(instruments); setProperty("InstrumentList",instruments); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index c8f78d96ef0d..c3c140bebe69 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -24,16 +24,16 @@ namespace Mantid /// Init method void CatalogListInvestigationTypes::init() { - declareProperty( new Kernel::ArrayProperty("InvestigationTypes",std::vector(), - boost::make_shared(), Kernel::Direction::Output), - "List of investigation types obtained from Catalog"); + declareProperty(new Kernel::ArrayProperty("InvestigationTypes",std::vector(), + boost::make_shared(), Kernel::Direction::Output), "A list containing investigation types."); + declareProperty("Session","","The session information of the catalog to use."); } /// exec method void CatalogListInvestigationTypes::exec() { std::vector investigationTypes; - API::CatalogManager::Instance().getCatalog("")->listInvestigationTypes(investigationTypes); + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))->listInvestigationTypes(investigationTypes); setProperty("InvestigationTypes",investigationTypes); } diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 7c25f4d447ae..0f95597808f6 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -25,13 +25,14 @@ namespace Mantid { declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the search results."); + declareProperty("Session","","The session information of the catalog to use."); } /// Execution method. void CatalogMyDataSearch::exec() { auto outputws = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); - API::CatalogManager::Instance().getCatalog("")->myData(outputws); + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))->myData(outputws); setProperty("OutputWorkspace",outputws); } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp index 02304466571e..4638ecce2b79 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp @@ -16,6 +16,7 @@ Datafiles and workspaces that are published are automatically made private. This #include "MantidICat/CatalogAlgorithmHelper.h" #include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/WorkspaceProperty.h" #include "MantidDataObjects/Workspace2D.h" @@ -60,6 +61,7 @@ namespace Mantid "This can only contain alphanumerics, underscores or periods."); declareProperty("InvestigationNumber","","The investigation number where the published file will be saved to."); declareProperty("DataFileDescription","","A short description of the datafile you are publishing to the catalog."); + declareProperty("Session","","The session information of the catalog to use."); } /// Execute the algorithm @@ -83,9 +85,10 @@ namespace Mantid { throw std::runtime_error("Please select a workspace or a file to publish. Not both."); } - // Cast a catalog to a catalogInfoService to access publishing functionality. - auto catalogInfoService = boost::dynamic_pointer_cast(CatalogAlgorithmHelper().createCatalog()); + auto catalogInfoService = boost::dynamic_pointer_cast( + API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))); + // Check if the catalog created supports publishing functionality. if (!catalogInfoService) throw std::runtime_error("The catalog that you are using does not support publishing to the archives."); diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index f7ed5b258195..9eba48c1e9f2 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -61,6 +61,8 @@ namespace Mantid declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace that will be created to store the ICat investigations search result."); declareProperty("NumberOfSearchResults", 0, "", Kernel::Direction::Output); + + declareProperty("Session","","The session information of the catalog to use."); } /// Execution method. @@ -73,7 +75,7 @@ namespace Mantid // Create output workspace. auto workspace = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); // Obtain all the active catalogs. - auto catalogs = API::CatalogManager::Instance().getCatalog(""); + auto catalogs = API::CatalogManager::Instance().getCatalog(getPropertyValue("Session")); // Search for investigations with user specific search inputs. setProperty("OutputWorkspace",workspace); // Do not perform a full search if we only want a COUNT search. From 10e967247f520b51630d3a175aa08ff033f798ac Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 3 Mar 2014 14:02:32 +0000 Subject: [PATCH 064/118] Export setPropertySettings method on Python PropertyManager. Refs #8947 --- .../kernel/src/Exports/IPropertyManager.cpp | 30 +++++++++++++++++-- .../kernel/src/Exports/IPropertySettings.cpp | 3 ++ .../mantid/kernel/src/Exports/Property.cpp | 5 +++- .../api/PythonAlgorithmPropertiesTest.py | 25 +++++++++++++++- .../mantid/kernel/EnabledWhenPropertyTest.py | 5 ++++ 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp index be628f1f2846..8da73daa0aec 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp @@ -6,7 +6,7 @@ #include #include -using Mantid::Kernel::IPropertyManager; +using namespace Mantid::Kernel; namespace Registry = Mantid::PythonInterface::Registry; using namespace boost::python; @@ -21,7 +21,7 @@ namespace * @param value :: The value of the property as a bpl object */ void setProperty(IPropertyManager &self, const std::string & name, - boost::python::object value) + const boost::python::object & value) { if( PyString_Check(value.ptr()) ) // String values can be set directly { @@ -40,6 +40,19 @@ namespace } } } + + /** + * Clones the given settingsManager and passes it on to the calling object as it takes ownership + * of the IPropertySettings object + * @param self The calling object + * @param propName A property name that will pick up the settings manager + * @param settingsManager The actual settings object + */ + void setPropertySettings(IPropertyManager &self, const std::string & propName, + IPropertySettings *settingsManager) + { + self.setPropertySettings(propName, settingsManager->clone()); + } } void export_IPropertyManager() @@ -48,19 +61,30 @@ void export_IPropertyManager() class_("IPropertyManager", no_init) .def("propertyCount", &IPropertyManager::propertyCount, "Returns the number of properties being managed") + .def("getProperty", &IPropertyManager::getPointerToProperty, return_value_policy(), "Returns the property of the given name. Use .value to give the value") + .def("getPropertyValue", &IPropertyManager::getPropertyValue, "Returns a string representation of the named property's value") + .def("getProperties", &IPropertyManager::getProperties, return_value_policy(), "Returns the list of properties managed by this object") + .def("setPropertyValue", &IPropertyManager::setPropertyValue, "Set the value of the named property via a string") + .def("setProperty", &setProperty, "Set the value of the named property") + + .def("setPropertySettings", &setPropertySettings, + "Assign the given IPropertySettings object to the named property") + .def("setPropertyGroup", &IPropertyManager::setPropertyGroup, "Set the group for a given property") + .def("existsProperty", &IPropertyManager::existsProperty, "Returns whether a property exists") - // Special methods so that IPropertyManager acts like a dictionary + + // Special methods so that IPropertyManager acts like a dictionary .def("__len__", &IPropertyManager::propertyCount) .def("__contains__", &IPropertyManager::existsProperty) .def("__getitem__", &IPropertyManager::getProperty) diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp index 685d7dd5af3b..5e8d17528bef 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertySettings.cpp @@ -1,12 +1,15 @@ #include "MantidKernel/IPropertySettings.h" #include "MantidKernel/IPropertyManager.h" #include +#include using Mantid::Kernel::IPropertySettings; using namespace boost::python; void export_IPropertySettings() { + register_ptr_to_python(); + class_("IPropertySettings", no_init) .def("isEnabled", &IPropertySettings::isEnabled, "Is the property to be shown as enabled in the GUI. Default true.") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp index a8be474e86f2..ab5bb181a4ca 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp @@ -1,4 +1,5 @@ #include "MantidKernel/Property.h" +#include "MantidKernel/IPropertySettings.h" #include "MantidPythonInterface/kernel/StlExportDefinitions.h" #include @@ -59,7 +60,9 @@ void export_Property() .add_property("allowedValues", &Property::allowedValues, "A list of allowed values") .add_property("getGroup", make_function(&Property::getGroup, return_value_policy()), - "Return the 'group' of the property, that is, the header in the algorithm's list of properties.") + "Return the 'group' of the property, that is, the header in the algorithm's list of properties.") + .add_property("settings", make_function(&Property::getSettings, return_value_policy()), + "Return the object managing this property's settings") ; } diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmPropertiesTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmPropertiesTest.py index 5666f4b250a5..5bd4527b81d9 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmPropertiesTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmPropertiesTest.py @@ -112,6 +112,29 @@ def PyExec(self): withdoc = alg.getProperty("WithDocString") self.assertTrue(isinstance(withdoc, FileProperty)) self.assertEquals(alg._testdocstring, withdoc.documentation) - + + + def test_passing_settings_object_connects_to_correct_object(self): + from mantid.kernel import EnabledWhenProperty, PropertyCriterion + + class DummyAlg(PythonAlgorithm): + + def PyInit(self): + self.declareProperty("BasicProp1",1) + self.declareProperty("BasicProp2",1) + self.setPropertySettings("BasicProp2", EnabledWhenProperty("BasicProp1", PropertyCriterion.IsDefault)) + + def PyExec(self): + pass + ## + alg = DummyAlg() + alg.initialize() + settings = alg.getProperty("BasicProp2").settings + self.assertTrue(settings is not None) + self.assertTrue(settings.isEnabled(alg)) + alg.setProperty("BasicProp1", 2) # not default + self.assertTrue(not settings.isEnabled(alg)) + + if __name__ == '__main__': unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py index 33da875bcaf3..1c349524fd38 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/EnabledWhenPropertyTest.py @@ -9,6 +9,11 @@ def test_construction_with_name_criterion_only_succeeds(self): def test_construction_with_name_criterion_value_succeeds(self): p = EnabledWhenProperty("OtherProperty", PropertyCriterion.IsEqualTo, "value") + def test_Property_Criterion_Has_Expected_Attrs(self): + attrs = ["IsNotDefault", "IsEqualTo", "IsNotEqualTo", "IsMoreOrEqual"] + for att in attrs: + self.assertTrue(hasattr(PropertyCriterion, att)) + #------------ Failure cases ------------------ def test_default_construction_raises_error(self): From afc25adab9b474776881e5dec99dc2ed2af65678 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 3 Mar 2014 14:08:44 +0000 Subject: [PATCH 065/118] Export VisibleWhenProperty to Python. Refs #8947 --- .../mantid/kernel/CMakeLists.txt | 1 + .../src/Exports/VisibleWhenProperty.cpp | 22 +++++++++++++++++ .../test/python/mantid/kernel/CMakeLists.txt | 1 + .../mantid/kernel/VisibleWhenPropertyTest.py | 24 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/VisibleWhenProperty.cpp create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/VisibleWhenPropertyTest.py diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index 5fae99cafc22..9de90f326cc1 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -15,6 +15,7 @@ set ( EXPORT_FILES src/Exports/IValidator.cpp src/Exports/IPropertySettings.cpp src/Exports/EnabledWhenProperty.cpp + src/Exports/VisibleWhenProperty.cpp src/Exports/PropertyWithValue.cpp src/Exports/ArrayProperty.cpp src/Exports/Quat.cpp diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/VisibleWhenProperty.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/VisibleWhenProperty.cpp new file mode 100644 index 000000000000..59ded113a4da --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/VisibleWhenProperty.cpp @@ -0,0 +1,22 @@ +#include "MantidKernel/VisibleWhenProperty.h" +#include + +using namespace Mantid::Kernel; +using namespace boost::python; + +void export_VisibleWhenProperty() +{ + class_, + boost::noncopyable>("VisibleWhenProperty", no_init) + .def(init( + (arg("otherPropName"), arg("when"), arg("value")), + "Enabled otherPropName property when value criterion meets that given by the 'when' argument") + ) + + .def(init( + (arg("otherPropName"), arg("when")), + "Enabled otherPropName property when criterion does not require a value, i.e isDefault") + ) + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt index c5fea345ad25..f0295f188230 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt @@ -31,6 +31,7 @@ set ( TEST_PY_FILES UnitFactoryTest.py UnitsTest.py V3DTest.py + VisibleWhenPropertyTest.py VMDTest.py ) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/VisibleWhenPropertyTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/VisibleWhenPropertyTest.py new file mode 100644 index 000000000000..1399338f872d --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/VisibleWhenPropertyTest.py @@ -0,0 +1,24 @@ +import unittest +from mantid.kernel import VisibleWhenProperty, PropertyCriterion + +class VisibleWhenPropertyTest(unittest.TestCase): + + def test_construction_with_name_criterion_only_succeeds(self): + p = VisibleWhenProperty("OtherProperty", PropertyCriterion.IsDefault) + + def test_construction_with_name_criterion_value_succeeds(self): + p = VisibleWhenProperty("OtherProperty", PropertyCriterion.IsEqualTo, "value") + + #------------ Failure cases ------------------ + + def test_default_construction_raises_error(self): + try: + VisibleWhenProperty() + self.fail("Expected default constructor to raise an error") + except Exception, e: + # boost.python.ArgumentError are not catchable + if "Python argument types in" not in str(e): + raise RuntimeError("Unexpected exception type raised") + +if __name__ == '__main__': + unittest.main() From 2747172dbd8bd5bdbc77952624dc4c1a25009599 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 14:13:44 +0000 Subject: [PATCH 066/118] Destroy all catalogs if empty sessionID. Refs #9084. - Updated `destroyCatalog` to reflect similar changes made to `getCatalog`. That is, it will now destroy all catalogs if no sessionID is provided when called. --- .../API/inc/MantidAPI/CatalogManager.h | 4 +--- .../Framework/API/src/CatalogManager.cpp | 22 +++++++++---------- .../Framework/ICat/src/CatalogLogout.cpp | 7 ++++-- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index 2f828740f671..b329883a7edb 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -41,10 +41,8 @@ namespace Mantid const std::string& endpoint,const std::string& facility); /// Get a specific catalog using the sessionID. ICatalog_sptr getCatalog(const std::string &sessionID); - /// Destroy and remove a specific catalog from the active catalogs list. + /// Destroy a specific catalog (if session provided), otherwise destroys all active catalogs. void destroyCatalog(const std::string &sessionID); - /// Destroy all active catalogs. - void destroyCatalogs(); private: /// These methods are required to create a singleton. diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index 1dc3a498467b..768cad239965 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -60,10 +60,20 @@ namespace Mantid /** * Destroy and remove a specific catalog from the active catalogs list and the composite catalog. + * If sessionID is empty then all catalogs are removed from the active catalogs list. * @param sessionID :: The session to search for in the active catalogs list. */ void CatalogManagerImpl::destroyCatalog(const std::string& sessionID) { + if(sessionID.empty()) + { + for(auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) + { + item->second->logout(); + } + m_activeCatalogs.clear(); + } + for(auto iter = m_activeCatalogs.begin(); iter != m_activeCatalogs.end(); ++iter) { if (sessionID == iter->first->getSessionId()) @@ -74,17 +84,5 @@ namespace Mantid } } - /** - * Destroy all active catalogs. - */ - void CatalogManagerImpl::destroyCatalogs() - { - for(auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) - { - item->second->logout(); - } - m_activeCatalogs.clear(); - } - } } diff --git a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp index 6ffa7e7bd4ee..46d7a4de5b81 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogLogout.cpp @@ -21,12 +21,15 @@ namespace Mantid } /// Init method to declare algorithm properties - void CatalogLogout::init() {} + void CatalogLogout::init() + { + declareProperty("Session","","The session information of the catalog to use."); + } /// execute the algorithm void CatalogLogout::exec() { - API::CatalogManager::Instance().destroyCatalogs(); + API::CatalogManager::Instance().destroyCatalog(getPropertyValue("Session")); } } } From 958100fa9bb9c4077e9c2c6da2903d381977e9db Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 14:45:16 +0000 Subject: [PATCH 067/118] Added getActiveSessions method. Refs #9084. --- .../Framework/API/inc/MantidAPI/CatalogManager.h | 4 +++- Code/Mantid/Framework/API/src/CatalogManager.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index b329883a7edb..726a1c5e2d5b 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -43,6 +43,8 @@ namespace Mantid ICatalog_sptr getCatalog(const std::string &sessionID); /// Destroy a specific catalog (if session provided), otherwise destroys all active catalogs. void destroyCatalog(const std::string &sessionID); + /// Obtains a list of the current active catalog sessions. + std::list getActiveSessions(); private: /// These methods are required to create a singleton. @@ -53,7 +55,7 @@ namespace Mantid virtual ~CatalogManagerImpl(); // Holds a list of active catalogs and uses their sessionId as unique identifier. - std::map m_activeCatalogs; + std::map m_activeCatalogs; }; #ifdef _WIN32 diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index 768cad239965..baf2d79f9414 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -84,5 +84,20 @@ namespace Mantid } } + /** + * Obtains a list of the current active catalog sessions. + * @return A list of active catalog sessions. + */ + std::list CatalogManagerImpl::getActiveSessions() + { + std::list sessions; + + for(auto item = m_activeCatalogs.begin(); item != m_activeCatalogs.end(); ++item) + { + sessions.push_back(item->first); + } + + return sessions; + } } } From 35f2bcb5777f8353cc56322156a0be5a97c6d5d5 Mon Sep 17 00:00:00 2001 From: Andrei Savici Date: Mon, 3 Mar 2014 10:14:52 -0500 Subject: [PATCH 068/118] Removed LoadNexusLog dependency. Refs #9106 --- .../DataHandling/test/RemoveLogsTest.h | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h b/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h index 5f2058191bfe..0a99f1531d3d 100644 --- a/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h +++ b/Code/Mantid/Framework/DataHandling/test/RemoveLogsTest.h @@ -5,7 +5,6 @@ #include "MantidDataHandling/RemoveLogs.h" #include "MantidDataHandling/LoadLog.h" -#include "MantidDataHandling/LoadNexusLogs.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidGeometry/Instrument.h" #include "MantidDataObjects/Workspace2D.h" @@ -17,7 +16,7 @@ #include "MantidGeometry/Instrument/Component.h" #include "MantidKernel/TimeSeriesProperty.h" #include - +#include "MantidTestHelpers/WorkspaceCreationHelper.h" using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::DataHandling; @@ -176,17 +175,35 @@ class RemoveLogsTest : public CxxTest::TestSuite void test_KeepLogs() { // Create an empty workspace and put it in the AnalysisDataService - Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",1,1,1); + EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace(1000,1,10000); outputSpace = "PartiallyRemoveLogs"; - TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(outputSpace, ws)); - LoadNexusLogs lnl; - if ( !lnl.isInitialized() ) lnl.initialize(); + // Add a bunch of logs + std::vector times; + std::vector index; + std::vector dbl1, dbl2; + DateAndTime startTime("2010-01-01T00:00:00"); + for (int i = 0; i < 100; ++i) + { + times.push_back(startTime + i*10.0); + index.push_back(i); + dbl1.push_back(i*0.1); + dbl2.push_back(6.0); + } + + auto scan_index = new TimeSeriesProperty("scan_index"); + scan_index->addValues(times,index); + ws->mutableRun().addProperty(scan_index); + auto dbl_prop1 = new TimeSeriesProperty("some_prop"); + auto dbl_prop2 = new TimeSeriesProperty("some_other_prop"); + dbl_prop1->addValues(times,dbl1); + dbl_prop2->addValues(times,dbl2); + ws->mutableRun().addProperty(dbl_prop1); + ws->mutableRun().addProperty(dbl_prop2); + ws->mutableRun().addProperty("Ei", 42.); + ws->mutableRun().addProperty("T0", 42.); + TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(outputSpace, ws)); - TS_ASSERT_THROWS_NOTHING(lnl.setPropertyValue("Filename", "CNCS_7860") ); - TS_ASSERT_THROWS_NOTHING(lnl.setPropertyValue("Workspace",outputSpace) ); - TS_ASSERT_THROWS_NOTHING(lnl.execute()); - TS_ASSERT( lnl.isExecuted() ); // Get back the saved workspace MatrixWorkspace_sptr output; @@ -194,16 +211,18 @@ class RemoveLogsTest : public CxxTest::TestSuite if ( !remover.isInitialized() ) remover.initialize(); TS_ASSERT_THROWS_NOTHING(remover.setPropertyValue("Workspace", outputSpace)); - TS_ASSERT_THROWS_NOTHING(remover.setPropertyValue("KeepLogs", "Speed5, gd_prtn_chrg")); + TS_ASSERT_THROWS_NOTHING(remover.setPropertyValue("KeepLogs", "Ei, scan_index")); TS_ASSERT_THROWS_NOTHING(remover.execute()); TS_ASSERT( remover.isExecuted() ); // log should have been removed - TS_ASSERT_THROWS( output->run().getLogData("Speed4"), std::runtime_error); - TS_ASSERT_THROWS_NOTHING( output->run().getLogData("Speed5")); - TS_ASSERT_THROWS_NOTHING( output->run().getLogData("gd_prtn_chrg")); + TS_ASSERT_THROWS( output->run().getLogData("some_other_prop"), std::runtime_error); + TS_ASSERT_THROWS( output->run().getLogData("some_prop"), std::runtime_error); + TS_ASSERT_THROWS( output->run().getLogData("T0"), std::runtime_error); + TS_ASSERT_THROWS_NOTHING( output->run().getLogData("Ei")); + TS_ASSERT_THROWS_NOTHING( output->run().getLogData("scan_index")); AnalysisDataService::Instance().remove(outputSpace); } From 21a90b49ddcd4f48385da42a35e4ab52f23d6f38 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 15:18:06 +0000 Subject: [PATCH 069/118] Removed unused createCatalog method. Refs #9084. --- .../inc/MantidICat/CatalogAlgorithmHelper.h | 2 -- .../ICat/src/CatalogAlgorithmHelper.cpp | 20 ------------------- 2 files changed, 22 deletions(-) diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogAlgorithmHelper.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogAlgorithmHelper.h index e6b4eb17b336..598fbda0c493 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogAlgorithmHelper.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogAlgorithmHelper.h @@ -13,8 +13,6 @@ namespace Mantid class CatalogAlgorithmHelper { public: - /// Create a catalog to use in the algorithms. - API::ICatalog_sptr createCatalog(); /// Obtain the error message returned by the IDS. const std::string getIDSError(Poco::Net::HTTPResponse::HTTPStatus &HTTPStatus, std::istream& responseStream); }; diff --git a/Code/Mantid/Framework/ICat/src/CatalogAlgorithmHelper.cpp b/Code/Mantid/Framework/ICat/src/CatalogAlgorithmHelper.cpp index 0e1150f06a8d..3bef4f2cbbdb 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogAlgorithmHelper.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogAlgorithmHelper.cpp @@ -8,26 +8,6 @@ namespace Mantid { namespace ICat { - - /** - * Create a catalog to use in the algorithms. - * @return A pointer to the catalog class. - */ - API::ICatalog_sptr CatalogAlgorithmHelper::createCatalog() - { - API::ICatalog_sptr catalog; - try - { - catalog = API::CatalogFactory::Instance().create(Kernel::ConfigService::Instance().getFacility().catalogInfo().catalogName()); - } - catch(Kernel::Exception::NotFoundError&) - { - throw std::runtime_error("Your current Facility: " + Kernel::ConfigService::Instance().getFacility().name() + " does not have catalog information.\n"); - } - return catalog; - } - - /** * Obtain the error message returned by the IDS. * @param HTTPStatus :: The HTTPStatus returned by the IDS. From 450540b06b1f8fbe3b23b91327200778ccfd3dcd Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 16:54:10 +0000 Subject: [PATCH 070/118] Ensure catalogdowndatafiles works. Refs #9084. --- Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp index 33ee01fcdb79..e7586bb1df0e 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp @@ -1,3 +1,4 @@ +#include "MantidAPI/CatalogManager.h" #include "MantidQtMantidWidgets/CatalogHelper.h" #include "MantidQtAPI/AlgorithmDialog.h" #include "MantidQtAPI/InterfaceManager.h" @@ -121,6 +122,10 @@ namespace MantidQt catalogAlgorithm->setProperty("FileNames",fileNames); catalogAlgorithm->setProperty("DownloadPath",downloadPath); + // This is temporary to ensure catalogdowndatafiles works as expected with one catalog. + auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); + catalogAlgorithm->setProperty("Session",session.front()->getSessionId()); + executeAsynchronously(catalogAlgorithm); // Return a vector containing the file paths to the files to download. return (catalogAlgorithm->getProperty("FileLocations")); From 49ac4a2225e499ce7e4074f7b0d242b30b712ab9 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 17:02:03 +0000 Subject: [PATCH 071/118] Prevent multiple facilities from existing. Refs #9084. --- Code/Mantid/Framework/API/src/CatalogManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index baf2d79f9414..423f458c73e9 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -24,6 +24,10 @@ namespace Mantid CatalogSession_sptr CatalogManagerImpl::login(const std::string& username,const std::string& password, const std::string& endpoint,const std::string& facility) { + // This is a temporary measure to ensure the user does not attempt to log into several facilities + // as that functionality is not quite supported. + if (m_activeCatalogs.size() >= 1) throw std::runtime_error("Multiple facility functionality is not yet supported."); + std::string className = Kernel::ConfigService::Instance().getFacility(facility).catalogInfo().catalogName(); auto catalog = CatalogFactory::Instance().create(className); CatalogSession_sptr session = catalog->login(username,password,endpoint,facility); From 073a26b840193fa2a71a5363b3dd12020d0e512b Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 17:07:24 +0000 Subject: [PATCH 072/118] Ensure CatalogPublish works with a catalog. Refs #9084. --- .../MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp index 480a239aa267..5fe66a5ce972 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp @@ -1,6 +1,7 @@ #include "MantidQtCustomDialogs/CatalogPublishDialog.h" #include "MantidAPI/CatalogFactory.h" +#include "MantidAPI/CatalogManager.h" #include "MantidAPI/ICatalog.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/ConfigService.h" @@ -63,9 +64,9 @@ namespace MantidQt void CatalogPublishDialog::populateUserInvestigations() { auto workspace = Mantid::API::WorkspaceFactory::Instance().createTable(); - std::string catalogName = Mantid::Kernel::ConfigService::Instance().getFacility().catalogInfo().catalogName(); - auto catalog = Mantid::API::CatalogFactory::Instance().create(catalogName); - catalog->myData(workspace); + // This again is a temporary measure to ensure publishing functionality will work with one catalog. + auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); + Mantid::API::CatalogManager::Instance().getCatalog(session.front()->getSessionId())->myData(workspace); // The user is not an investigator on any investigations and cannot publish // or they are not logged into the catalog then update the related message.. From 32697789a54e996e8692af65b3140376bd7fb972 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 17:07:52 +0000 Subject: [PATCH 073/118] Remove unnecessary destructor. Refs #9084. --- .../inc/MantidQtCustomDialogs/CatalogPublishDialog.h | 2 -- .../Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp | 3 --- 2 files changed, 5 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/CatalogPublishDialog.h b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/CatalogPublishDialog.h index 7b142fae67e3..2ccd8c95df27 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/CatalogPublishDialog.h +++ b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/CatalogPublishDialog.h @@ -40,8 +40,6 @@ namespace MantidQt public: /// Constructor CatalogPublishDialog(QWidget *parent = 0); - /// Destructor - ~CatalogPublishDialog(); private: /// Create the inital layout. diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp index 5fe66a5ce972..722fbf2354f0 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp @@ -22,9 +22,6 @@ namespace MantidQt */ CatalogPublishDialog::CatalogPublishDialog(QWidget *parent) : MantidQt::API::AlgorithmDialog(parent), m_uiForm() {} - /// Destructor - CatalogPublishDialog::~CatalogPublishDialog() {} - /// Initialise the layout void CatalogPublishDialog::initLayout() { From 56bc69f293e35cf62c2f06938e396006f8ae42e4 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Mon, 3 Mar 2014 17:11:59 +0000 Subject: [PATCH 074/118] Set session property in publish algorithm. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogPublish.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp index 4638ecce2b79..5e55b8a21f98 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp @@ -85,6 +85,11 @@ namespace Mantid { throw std::runtime_error("Please select a workspace or a file to publish. Not both."); } + + // This again is a temporary measure to ensure publishing functionality will work with one catalog. + auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); + setPropertyValue("Session", session.front()->getSessionId()); + // Cast a catalog to a catalogInfoService to access publishing functionality. auto catalogInfoService = boost::dynamic_pointer_cast( API::CatalogManager::Instance().getCatalog(getPropertyValue("Session"))); From f8fb67a6983423a1e03f253a288c364400a108ca Mon Sep 17 00:00:00 2001 From: Vickie Lynch Date: Mon, 3 Mar 2014 16:02:44 -0500 Subject: [PATCH 075/118] Refs #9108 input parameters for sample offset --- .../inc/MantidCrystal/SCDPanelErrors.h | 7 ----- .../Crystal/src/SCDCalibratePanels.cpp | 22 ++++++++----- .../Framework/Crystal/src/SCDPanelErrors.cpp | 31 ++++++------------- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h index 3435ff012f0e..01912bbcc46d 100644 --- a/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h +++ b/Code/Mantid/Framework/Crystal/inc/MantidCrystal/SCDPanelErrors.h @@ -173,13 +173,6 @@ class DLLExport SCDPanelErrors : public API::ParamFunction, public API::IFuncti bool a_set,b_set,c_set,alpha_set,beta_set,gamma_set,PeakName_set, BankNames_set, startX_set,endX_set, NGroups_set, sampleX_set, sampleY_set, sampleZ_set; - /** - * 0 - no action - * 1- init called no declare - * 2- init Called and samp offset parameters are declared - */ - int SampOffsetDeclareStatus; - double tolerance; /// The OrientedLattice created from the parameters diff --git a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp index daed93e21c9d..144eab878f57 100644 --- a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp +++ b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp @@ -695,6 +695,9 @@ namespace Mantid bool use_PanelHeight = getProperty("usePanelHeight"); bool use_PanelPosition = getProperty("usePanelPosition"); bool use_PanelOrientation = getProperty("usePanelOrientation"); + double SampleXoffset = getProperty("SampleXoffset"); + double SampleYoffset = getProperty("SampleYoffset"); + double SampleZoffset = getProperty("SampleZoffset"); string Grouping = getProperty( "PanelGroups"); string bankPrefix = getProperty("PanelNamePrefix"); @@ -874,18 +877,18 @@ namespace Mantid constrain(iFunc, paramPrefix+"Zrot", -1.*MaxRotOffset, MaxRotOffset); }//for vector< string > in Groups + // Function supports setting the sample position even when it isn't be refined + iFunc->setAttributeValue("SampleX", samplePos.X() + SampleXoffset); + iFunc->setAttributeValue("SampleY", samplePos.Y() + SampleYoffset); + iFunc->setAttributeValue("SampleZ", samplePos.Z() + SampleZoffset); + // Constraints for sample offsets if( getProperty("AllowSampleShift")) { - // TODO the function should support setting the sample position even when it isn't be refined - iFunc->setAttributeValue("SampleX", samplePos.X()); - iFunc->setAttributeValue("SampleY", samplePos.Y()); - iFunc->setAttributeValue("SampleZ", samplePos.Z()); - maxXYOffset = getProperty("MaxSamplePositionChangeMeters"); - constrain(iFunc, "SampleX", samplePos.X()-maxXYOffset, samplePos.X()+ maxXYOffset); - constrain(iFunc, "SampleY", samplePos.Y()-maxXYOffset, samplePos.Y()+maxXYOffset); - constrain(iFunc, "SampleZ", samplePos.Z()-maxXYOffset, samplePos.Z()+maxXYOffset); + constrain(iFunc, "SampleX", samplePos.X()+ SampleXoffset-maxXYOffset, samplePos.X()+ SampleXoffset+ maxXYOffset); + constrain(iFunc, "SampleY", samplePos.Y()+ SampleYoffset-maxXYOffset, samplePos.Y()+ SampleYoffset+maxXYOffset); + constrain(iFunc, "SampleZ", samplePos.Z()+ SampleZoffset-maxXYOffset, samplePos.Z()+ SampleZoffset+maxXYOffset); } tie(iFunc, !useL0, "l0", L0); @@ -1397,6 +1400,9 @@ namespace Mantid declareProperty("usePanelOrientation", true, "Fit the PanelOrientation"); declareProperty("RotateCenters", false,"Rotate bank Centers with panel orientations"); declareProperty("AllowSampleShift",false,"Allow and fit for a sample that is off center"); + declareProperty("SampleXoffset", 0.0, "Specify Sample x offset"); + declareProperty("SampleYoffset", 0.0, "Specify Sample y offset"); + declareProperty("SampleZoffset", 0.0, "Specify Sample z offset"); // ---------- preprocessing vector< string > preProcessOptions; diff --git a/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp b/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp index 2f6e1740ff6d..b232b7de4505 100644 --- a/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp +++ b/Code/Mantid/Framework/Crystal/src/SCDPanelErrors.cpp @@ -166,7 +166,6 @@ SCDPanelErrors::SCDPanelErrors() : NGroups =1; RotateCenters= false; SampleOffsets=false; - SampOffsetDeclareStatus=0; } SCDPanelErrors::~SCDPanelErrors() @@ -288,14 +287,9 @@ void SCDPanelErrors::init() declareParameter("l0", 0.0, "Initial Flight Path"); declareParameter("t0", 0.0, "Time offset"); - SampOffsetDeclareStatus=1; - if( SampleOffsets) - { - declareParameter("SampleX", 0.0, "Sample x offset"); - declareParameter("SampleY", 0.0, "Sample y offset"); - declareParameter("SampleZ", 0.0, "Sample z offset"); - SampOffsetDeclareStatus = 2; - } + declareParameter("SampleX", 0.0, "Sample x offset"); + declareParameter("SampleY", 0.0, "Sample y offset"); + declareParameter("SampleZ", 0.0, "Sample z offset"); } void SCDPanelErrors::getPeaks() const @@ -431,13 +425,12 @@ Instrument_sptr SCDPanelErrors::getNewInstrument(const API::IPeak & peak) const pmapSv,RotateCenters); }//for each group + V3D SampPos= instChange->getSample()->getPos(); - if( SampleOffsets) - { - SampPos[0]+=getParameter("SampleX"); - SampPos[1]+=getParameter("SampleY"); - SampPos[2]+=getParameter("SampleZ"); - } + SampPos[0]+=getParameter("SampleX")+SampleX; + SampPos[1]+=getParameter("SampleY")+SampleY; + SampPos[2]+=getParameter("SampleZ")+SampleZ; + SCDCalibratePanels::FixUpSourceParameterMap( instChange, getParameter("l0"),SampPos, pmapSv) ; return instChange; @@ -1455,13 +1448,7 @@ void SCDPanelErrors::setAttribute(const std::string &attName, const Attribute & SampleOffsets= false; else SampleOffsets=true; - if(SampOffsetDeclareStatus== 1 && SampleOffsets) - { - declareParameter("SampleX", 0.0, "Sample x offset"); - declareParameter("SampleY", 0.0, "Sample y offset"); - declareParameter("SampleZ", 0.0, "Sample z offset"); - SampOffsetDeclareStatus =2; - } + } else if (attName == SAMPLE_X) { From 3749fe5c4da95416372a69716961067e1b2213f8 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 10:06:12 +0000 Subject: [PATCH 076/118] Fix coverity issue. Refs #9084. --- Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index 704c9fd36e48..ab6348534536 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -646,9 +646,9 @@ namespace Mantid LONG64 fileID = fileId; request.datafileId = &fileID; - // get the URL using ICAT API - int ret=icat.downloadDatafile(&request,&response); - if(ret == 0 && !response.URL) + int ret = icat.downloadDatafile(&request,&response); + + if(ret == 0) { downloadURL = *response.URL; } From 8de645fb134645e4d62da9cc23b31431c39ae311 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 10:07:08 +0000 Subject: [PATCH 077/118] Minor type consistency improvement. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h | 2 +- Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h index 9c3393449ac4..807aecdb61e5 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h @@ -83,7 +83,7 @@ namespace Mantid Kernel::Logger& m_log; }; - ///Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) . + ///Forward declaration of a specialisation of SingletonHolder for CatalogFactoryImpl (needed for dllexport/dllimport) . #ifdef _WIN32 // this breaks new namespace declaraion rules; need to find a better fix template class MANTID_API_DLL Mantid::Kernel::SingletonHolder; diff --git a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp index ab6348534536..3728d01cbc7e 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/ICat3Helper.cpp @@ -113,7 +113,7 @@ namespace Mantid std::string sessionID = m_session->getSessionId(); request.sessionId = &sessionID; - LONG64 investigationID = invstId; + int64_t investigationID = invstId; request.investigationId= &investigationID; request.investigationInclude = &include; @@ -216,7 +216,7 @@ namespace Mantid std::string sessionID = m_session->getSessionId(); request.sessionId = &sessionID; request.investigationInclude = &include; - LONG64 investigationID = invstId; + int64_t investigationID = invstId; request.investigationId = &investigationID; int result = icat.getInvestigationIncludes(&request,&response); @@ -643,7 +643,7 @@ namespace Mantid std::string sessionID = m_session->getSessionId(); request.sessionId = &sessionID; - LONG64 fileID = fileId; + int64_t fileID = fileId; request.datafileId = &fileID; int ret = icat.downloadDatafile(&request,&response); @@ -671,7 +671,7 @@ namespace Mantid std::string sessionID = m_session->getSessionId(); request.sessionId = &sessionID; - LONG64 fileID = fileid; + int64_t fileID = fileid; request.datafileId = &fileID; int ret=icat.getDatafile(&request,&response); From 61c208115cc813d659ef3005c9bb3ca2e108ad04 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 4 Mar 2014 11:35:32 +0000 Subject: [PATCH 078/118] re #3153 Remember log level --- Code/Mantid/MantidPlot/src/ApplicationWindow.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 8440beae64ee..4dec9114de13 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -337,6 +337,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) resultsLog = new MessageDisplay(MessageDisplay::EnableLogLevelControl, logWindow); logWindow->setWidget(resultsLog); connect(resultsLog, SIGNAL(errorReceived(const QString &)), logWindow, SLOT(show())); + // Start Mantid // Set the Paraview path BEFORE libaries are loaded. Doing it here prevents @@ -495,6 +496,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) renamedTables = QStringList(); if (!factorySettings) readSettings(); + createLanguagesList(); insertTranslatedStrings(); disableToolbars(); @@ -4997,6 +4999,10 @@ void ApplicationWindow::readSettings() changeAppStyle(settings.value("/Style", appStyle).toString()); autoSave = settings.value("/AutoSave", false).toBool(); autoSaveTime = settings.value("/AutoSaveTime",15).toInt(); + //set logging level to the last saved level + int lastLoggingLevel = settings.value("/LastLoggingLevel", Mantid::Kernel::Logger::Priority::PRIO_NOTICE).toInt(); + Mantid::Kernel::Logger::setLevelForAll(lastLoggingLevel); + d_backup_files = settings.value("/BackupProjects", true).toBool(); d_init_window_type = (WindowType)settings.value("/InitWindow", NoWindow).toInt(); defaultScriptingLang = settings.value("/ScriptingLang","Python").toString(); //Mantid M. Gigg @@ -5456,6 +5462,10 @@ void ApplicationWindow::saveSettings() settings.setValue("/Style", appStyle); settings.setValue("/AutoSave", autoSave); settings.setValue("/AutoSaveTime", autoSaveTime); + //save current logger level from the root logger "" + int lastLoggingLevel = Mantid::Kernel::Logger::get("").getLevel(); + settings.setValue("/LastLoggingLevel", lastLoggingLevel); + settings.setValue("/BackupProjects", d_backup_files); settings.setValue("/InitWindow", static_cast(d_init_window_type)); From e64be911c058a90cbdc0d0565c1b491fe4c36d67 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 4 Mar 2014 12:08:19 +0000 Subject: [PATCH 079/118] Added a new icon for Remove Error Bars on the graph menu To Test: 1. Start Mantidplot, load some data and create a line graph 1. With the graph selected open the graph menu 1. the Add error bars and remove error bars icons should be different and make sense. re #3812 --- .../MantidPlot/src/ApplicationWindow.cpp | 2 +- Code/Mantid/MantidPlot/src/pixmaps.cpp | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 8440beae64ee..a7503ace6c5c 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -12783,7 +12783,7 @@ void ApplicationWindow::createActions() actionAddErrorBars->setShortcut( tr("Ctrl+B") ); connect(actionAddErrorBars, SIGNAL(activated()), this, SLOT(addErrorBars())); - actionRemoveErrorBars = new QAction(QIcon(getQPixmap("errors_xpm")), tr("Remove Error Bars..."), this); + actionRemoveErrorBars = new QAction(QIcon(getQPixmap("errors_remove_xpm")), tr("Remove Error Bars..."), this); //actionRemoveErrorBars->setShortcut( tr("Ctrl+B") ); connect(actionRemoveErrorBars, SIGNAL(activated()), this, SLOT(removeErrorBars())); diff --git a/Code/Mantid/MantidPlot/src/pixmaps.cpp b/Code/Mantid/MantidPlot/src/pixmaps.cpp index 790627a7655f..20da746ce732 100644 --- a/Code/Mantid/MantidPlot/src/pixmaps.cpp +++ b/Code/Mantid/MantidPlot/src/pixmaps.cpp @@ -8477,6 +8477,30 @@ static const char *errors_xpm[]={ " . ", "..."}; +/* XPM */ +static const char *errors_remove_xpm[]={ +/* width height num_colors chars_per_pixel */ +"11 11 5 1", +/* colors */ +" c None", +". c #000000", +"X c #ff6666", +"o c #ff0000", +"O c #980000", +/* pixels */ +" ... Xo", +" . XoX", +" . XoX ", +" .XoX ", +" .OoX ", +" OoO ", +" XoO. ", +" XoX. ", +" XoX . ", +"XoX . ", +"oX ... " +}; + static const char *curves_xpm[]={ "14 16 5 1", " c None", @@ -12902,6 +12926,7 @@ QPixmap getQPixmap(const std::string &name) else if (name == "logo_xpm") return QPixmap(logo_xpm); else if (name == "hand_xpm") return QPixmap(hand_xpm); else if (name == "errors_xpm") return QPixmap(errors_xpm); + else if (name == "errors_remove_xpm") return QPixmap(errors_remove_xpm); else if (name == "curves_xpm") return QPixmap(curves_xpm); else if (name == "arrow_xpm") return QPixmap(arrow_xpm); else if (name == "legend_xpm") return QPixmap(legend_xpm); From d31f57a07be9eeb0da703a86b6b9ba145e6ce136 Mon Sep 17 00:00:00 2001 From: Karl Palmen Date: Tue, 4 Mar 2014 14:41:38 +0000 Subject: [PATCH 080/118] Improve Flowchart and correct description of SecondPeriod re #9047 Signed-off-by: Karl Palmen --- .../Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml | 2 +- Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml index c859838cf045..9e86f5196600 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml +++ b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp index 6b2bc19d0aca..708dc07c77e4 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp +++ b/Code/Mantid/Framework/WorkflowAlgorithms/src/MuonLoad.cpp @@ -78,7 +78,7 @@ namespace WorkflowAlgorithms "The name of the Nexus file to load" ); declareProperty("FirstPeriod", 0, "Group index of the first period workspace to use"); - declareProperty("SecondPeriod", EMPTY_INT(), "Group index of the first period workspace to use"); + declareProperty("SecondPeriod", EMPTY_INT(), "Group index of the second period workspace to use"); std::vector allowedOperations; allowedOperations.push_back("+"); From 38e22f1aecf585efd38f3b9f3afc6f4220a8fd03 Mon Sep 17 00:00:00 2001 From: Karl Palmen Date: Tue, 4 Mar 2014 15:49:56 +0000 Subject: [PATCH 081/118] Modify the display of default handling in flowchart re #9047 Signed-off-by: Karl Palmen --- .../Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml index 9e86f5196600..245f45dc5a2f 100644 --- a/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml +++ b/Code/Mantid/Framework/WorkflowAlgorithms/doc/diagrams/MuonWorkflow.xml @@ -1 +1 @@ -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 \ No newline at end of file +1Ztfk6I4EMA/jY9nAeHv4yyzM3dVt7dTN1O1c/dylZGo1AKhQpjRb79BOihRPEFARktLgob0L013pzvOkB9vHhlO199oQKKZocWYr2fofmYYmniJhhSvyO8kXK152azrtrc/8yMM5Pddw963Py9wROAH+9Zaw5JGQa1hQZOELORlyjZOacTDNKs1rvIwIEoTC+udBVsYlQZyBBulIeNbOcSALHEe8d92TeKcMUNfBRpGqRhN8Sne+CQq8MirQB8z46HhC5XUjCQgUuNv3nGUw0gewogkOCZHQ8zWOC0+xptVMV3zZUQ/FmvM+Dzj4v0/fYa+LMMo8mlE2e4n6EE8fF+0Z5zRn+TgjLZ7VGfkJO4k34tgHYsAUr0Txgnw3DWBPI+ExoSzrfjKx14xPNAXmBELOMDvkavP4UoY5nRVdVO0rg+Uz1YZig+AsRHpnxQH33Ka/EU2edaCa8rogmRiSCpX3y/Iduda3SZXctVNoAFgdZWs5Q1L9ggmSYI7xuiHOFpEOMvCxRELVGfhNrIggWIvMpqzBTSBWELzV0QKcJrXackZiTAP3+sXaCP6XZpG23uCg5cwFhrA2BQUC8Hx9ZplVJoDumV4I+tWccc+Mpqn94QLp0DZJG5d0+yNMGg+8DV1R/KUhG1j7gyKuFDdfwmjU/A1ZhVT9OtsTAkGOrBs6HUYpP4aJyvyJUy+L5eZsEwTUFnrRCTSUWVtxShYpqqy6HKj4AzmcISYbPsqmgo93R38Iw40MTQ4fCJMqD4nBUcYRUWr2YSedUhSfw89Ukn+CpcEP32ioRhKRd02nbmYDOR6yNUsBIOBKbBdRb/LQUIXx7yrYV2s4YymPyj7maVYyD4F/e4tnNLr4ZStujxHb2GQu6j3axwmkwj8m6Oy6yJ/t24vdOHiBvVwrzHeTALoQN7NdiuAsgtLGzhq+Ju8tdLS4ZZRfcVibv2+d42jUMy1B4ZaRLs+jha58AHkLtvGB33flrLT25pCeibA7CmRGULWXK7rLoBcKX4bzA8hy/gTDtkfSSBGPgHL4PTlvRTL4MncgOxA09vQ7aDCz0Tk74JpwXWGgStgKnR1SGsMg/YuStd4EkAH8mOuq5pcy4NLD0P0e87TnL9sBcAJYJUOqHeslorV0LSBzYCfZ5zGMjP2gt8E1ykg7m2VIGM5mRhTTYExSgD2hBmO26TEhiM7kE1wTDW2tWQC4HbZ7Jrkcn3YNlcgidWy17tgdrT09YWJlE3IqzyK+HyQRhFHZ7IoXnPO6SwZGQ0dkikD0EmRqcvaMWMkg5NeZT2dMfIcbe5qnlA8USLwkLJilHXJoTJG7Yk2L+zOEz1xX01ee5qLrOdtCEzaDWUtY6guucAAc/yGM3Gyb2fk9ZcMrKrSVdBvqQ4J2V6LaEq6i5ErrF7zIuj83QQXP9SwEu9oGiZLf7s6YJisJhNN6lpvdUBZOGgIJwdeBzXfve0VTUfQ0FbTTjj9spI9mqL1i6Gj+5LV+0MOZb35k3Jo4dpGKJuZjroYNtFxQac5+Dnq0JKmv+oOHXmDUq7+Yql+J6jZWZ7ffHNq0sb1DP1y6OghZeXxhuu4fjl03IwlCzGfKe7WUXPa4vykA6QbKn97YWUxoLWwp3Y1jCvsLvabTEVBN/vaTaPWa5TNBvZ+/TGRbJdudkx0VMw+lX0wOzpHmWi+YTR7X+5mb+MSDm4EVyueCo2u26JOwCgBTRNGtXOsMAT/v3PsYnr9LYxg5Tm1RPEVO+50q+N6qVqEj7RgEof7P4SU4fv+jzPo6y8= \ No newline at end of file From ae8afaafebe80e93ba09a365e2d644308c813ed1 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 16:55:12 +0000 Subject: [PATCH 082/118] Move input property above output. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp | 2 +- Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp | 2 +- Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp | 2 +- Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp | 2 +- .../Framework/ICat/src/CatalogListInvestigationTypes.cpp | 2 +- Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp | 2 +- Code/Mantid/Framework/ICat/src/CatalogSearch.cpp | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp index 10ea25ac0d8f..5ffa842e3f5a 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogDownloadDataFiles.cpp @@ -52,11 +52,11 @@ namespace Mantid declareProperty(new ArrayProperty ("FileIds"),"List of fileids to download from the data server"); declareProperty(new ArrayProperty ("FileNames"),"List of filenames to download from the data server"); declareProperty("DownloadPath","", "The path to save the files to download to."); + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new ArrayProperty("FileLocations",std::vector(), boost::make_shared(), Direction::Output), "A list of file locations to the catalog datafiles."); - declareProperty("Session","","The session information of the catalog to use."); } /// Execute the algorithm diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp index 664ecffcc7a2..c9cb5bc98cff 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataFiles.cpp @@ -27,9 +27,9 @@ namespace Mantid { declareProperty("InvestigationId","",boost::make_shared>(), "ID of the selected investigation"); + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the data file search details"); - declareProperty("Session","","The session information of the catalog to use."); } //execute the algorithm diff --git a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp index 6fc4b42aebee..fff0b3f0d22a 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogGetDataSets.cpp @@ -26,9 +26,9 @@ namespace Mantid { declareProperty("InvestigationId","",boost::make_shared>(), "ID of the selected investigation"); + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the result of datasets search "); - declareProperty("Session","","The session information of the catalog to use."); } /// exec methods diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp index 6ef4be69a628..bf4d3d4459e6 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInstruments.cpp @@ -25,9 +25,9 @@ namespace Mantid /// Init method void CatalogListInstruments::init() { + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new Kernel::ArrayProperty("InstrumentList",std::vector(), boost::make_shared(),Kernel::Direction::Output), "A list containing instrument names."); - declareProperty("Session","","The session information of the catalog to use."); } /// exec method diff --git a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp index c3c140bebe69..76b8c1926e59 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogListInvestigationTypes.cpp @@ -24,9 +24,9 @@ namespace Mantid /// Init method void CatalogListInvestigationTypes::init() { + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new Kernel::ArrayProperty("InvestigationTypes",std::vector(), boost::make_shared(), Kernel::Direction::Output), "A list containing investigation types."); - declareProperty("Session","","The session information of the catalog to use."); } /// exec method diff --git a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp index 0f95597808f6..3254c34f6351 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogMyDataSearch.cpp @@ -23,9 +23,9 @@ namespace Mantid /// Initialisation method. void CatalogMyDataSearch::init() { + declareProperty("Session","","The session information of the catalog to use."); declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace to store the search results."); - declareProperty("Session","","The session information of the catalog to use."); } /// Execution method. diff --git a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp index 9eba48c1e9f2..d411bb113d12 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogSearch.cpp @@ -58,11 +58,11 @@ namespace Mantid declareProperty("Limit", 0, ""); declareProperty("Offset",0, ""); + declareProperty("Session","","The session information of the catalog to use."); + declareProperty(new API::WorkspaceProperty ("OutputWorkspace", "", Kernel::Direction::Output), "The name of the workspace that will be created to store the ICat investigations search result."); declareProperty("NumberOfSearchResults", 0, "", Kernel::Direction::Output); - - declareProperty("Session","","The session information of the catalog to use."); } /// Execution method. From 8198a56f38a5e19a40874a0461c616ec56c35464 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 17:12:47 +0000 Subject: [PATCH 083/118] Return by value instead of const reference. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h | 6 +++--- Code/Mantid/Framework/API/src/CatalogSession.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h index 23087f80f0da..85d616717a35 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -38,10 +38,10 @@ namespace Mantid { public: CatalogSession(const std::string &sessionID, const std::string &facility, const std::string &endpoint); - const std::string& getSessionId() const; + std::string getSessionId() const; void setSessionId(const std::string &sessionID); - const std::string& getSoapEndpoint() const; - const std::string& getFacility() const; + std::string getSoapEndpoint() const; + std::string getFacility() const; private: std::string m_sessionID; diff --git a/Code/Mantid/Framework/API/src/CatalogSession.cpp b/Code/Mantid/Framework/API/src/CatalogSession.cpp index 9b7b92881a6d..2218e022d0e9 100644 --- a/Code/Mantid/Framework/API/src/CatalogSession.cpp +++ b/Code/Mantid/Framework/API/src/CatalogSession.cpp @@ -18,7 +18,7 @@ namespace Mantid * Obtain the session ID for the catalog created. * @return The sesssion Id of the catalog created. */ - const std::string& CatalogSession::getSessionId() const + std::string CatalogSession::getSessionId() const { return m_sessionID; } @@ -36,7 +36,7 @@ namespace Mantid * Obtains the soap end-point of the catalog created. * @return The soap end-point used to create the catalog. */ - const std::string& CatalogSession::getSoapEndpoint() const + std::string CatalogSession::getSoapEndpoint() const { return m_endpoint; } @@ -45,7 +45,7 @@ namespace Mantid * Obtain the facility of the catalog created. * @return The facility used to create the catalog. */ - const std::string& CatalogSession::getFacility() const + std::string CatalogSession::getFacility() const { return m_facility; } From 70c5d14c329e4bbb4231814cd2c4ffb3d2f48b9d Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 17:19:22 +0000 Subject: [PATCH 084/118] Prevent crash on manual algorithm use. Refs #9084. --- Code/Mantid/Framework/ICat/src/CatalogPublish.cpp | 2 +- .../Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp | 3 ++- Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp index 5e55b8a21f98..0a95f6ca62ae 100644 --- a/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp +++ b/Code/Mantid/Framework/ICat/src/CatalogPublish.cpp @@ -88,7 +88,7 @@ namespace Mantid // This again is a temporary measure to ensure publishing functionality will work with one catalog. auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); - setPropertyValue("Session", session.front()->getSessionId()); + if (!session.empty()) setPropertyValue("Session", session.front()->getSessionId()); // Cast a catalog to a catalogInfoService to access publishing functionality. auto catalogInfoService = boost::dynamic_pointer_cast( diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp index 722fbf2354f0..f238da738d5d 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp @@ -63,7 +63,8 @@ namespace MantidQt auto workspace = Mantid::API::WorkspaceFactory::Instance().createTable(); // This again is a temporary measure to ensure publishing functionality will work with one catalog. auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); - Mantid::API::CatalogManager::Instance().getCatalog(session.front()->getSessionId())->myData(workspace); + if (!session.empty()) + Mantid::API::CatalogManager::Instance().getCatalog(session.front()->getSessionId())->myData(workspace); // The user is not an investigator on any investigations and cannot publish // or they are not logged into the catalog then update the related message.. diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp index e7586bb1df0e..7a21e1b72ddb 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/CatalogHelper.cpp @@ -124,7 +124,7 @@ namespace MantidQt // This is temporary to ensure catalogdowndatafiles works as expected with one catalog. auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); - catalogAlgorithm->setProperty("Session",session.front()->getSessionId()); + if (!session.empty()) catalogAlgorithm->setProperty("Session",session.front()->getSessionId()); executeAsynchronously(catalogAlgorithm); // Return a vector containing the file paths to the files to download. From daa4a28a65ca6cc30d16cc37fb34ac35d584ed26 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Tue, 4 Mar 2014 18:26:12 +0000 Subject: [PATCH 085/118] Attempt to fix cpp error. Refs #9084. --- Code/Mantid/Framework/API/src/CatalogManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/API/src/CatalogManager.cpp b/Code/Mantid/Framework/API/src/CatalogManager.cpp index 423f458c73e9..b8f282783d2d 100644 --- a/Code/Mantid/Framework/API/src/CatalogManager.cpp +++ b/Code/Mantid/Framework/API/src/CatalogManager.cpp @@ -78,12 +78,13 @@ namespace Mantid m_activeCatalogs.clear(); } - for(auto iter = m_activeCatalogs.begin(); iter != m_activeCatalogs.end(); ++iter) + for(auto iter = m_activeCatalogs.begin(); iter != m_activeCatalogs.end();) { if (sessionID == iter->first->getSessionId()) { iter->second->logout(); m_activeCatalogs.erase(iter); + return; } } } From 672fef93ae577b3e5237aaed5e7bdf53d1e1692f Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Tue, 4 Mar 2014 14:37:25 -0500 Subject: [PATCH 086/118] Re #9118. Remove unused code. --- .../Geometry/test/IMDDimensionFactoryTest.h | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h index 16ee64cdac92..16f897dc2f4e 100644 --- a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h @@ -37,30 +37,6 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite return pDoc->documentElement(); } - static Poco::XML::Element* constructReciprocalDimensionXML() - { - std::string xmlToParse = std::string("") + "Qz" - + "6.6" + "-6.6" - + "6" - + "q3" + ""; - - Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); - return pDoc->documentElement(); - } - - static Poco::XML::Element* constructUnknownReciprocalDimensionXML() - { - std::string xmlToParse = std::string("") + "Qz" - + "6.6" + "-6.6" - + "6" - + "unknown" + ""; - - Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); - return pDoc->documentElement(); - } - static std::string constructNonReciprocalDimensionXMLString() { return std::string("") + "Energy" From 271efdf72040a7c9bc1635b83a19637dd27edfed Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Tue, 4 Mar 2014 14:53:31 -0500 Subject: [PATCH 087/118] Re #9118. Update test to use factory in way I expect it to end up. Obviously, this won't compile until I've refactored the class itself. --- .../Geometry/test/IMDDimensionFactoryTest.h | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h index 16f897dc2f4e..4280a12d7e9c 100644 --- a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h @@ -5,6 +5,7 @@ #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include #include +#include using namespace Mantid::Geometry; @@ -12,7 +13,7 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite { private: - static Poco::XML::Element* constructDimensionWithUnits() + std::string constructDimensionWithUnitsXMLString() { std::string xmlToParse = std::string("") + "Qz" + "Cubits" @@ -20,77 +21,66 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite + "8" + "q3" + ""; - Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); - return pDoc->documentElement(); + return xmlToParse; } - static Poco::XML::Element* constructDimensionWithoutUnits() + std::string constructDimensionWithoutUnitsXMLString() { std::string xmlToParse = std::string("") + "Qz" + "3" + "-3" + "8" + "q3" + ""; - Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); - return pDoc->documentElement(); + return xmlToParse; } - static std::string constructNonReciprocalDimensionXMLString() + std::string constructNonReciprocalDimensionXMLString() { return std::string("") + "Energy" + "150" + "0" + "4" + ""; } - static Poco::XML::Element* constructNonReciprocalDimensionXML() + Poco::AutoPtr constructNonReciprocalDimensionXML() { std::string xmlToParse = constructNonReciprocalDimensionXMLString(); Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); - return pDoc->documentElement(); + return pParser.parseString(xmlToParse); } public: void testCorrectGeneration() { - using namespace Mantid::Geometry; - IMDDimensionFactory factory(constructDimensionWithUnits()); - IMDDimension* dimension = factory.create(); + IMDDimension_const_sptr dimension = IMDDimensionFactory::create(constructDimensionWithUnitsXMLString()); TS_ASSERT_EQUALS("Cubits", dimension->getUnits()); TS_ASSERT_EQUALS("Qz", dimension->getName()); TS_ASSERT_EQUALS("qz", dimension->getDimensionId()); TS_ASSERT_EQUALS(-3, dimension->getMinimum()); TS_ASSERT_EQUALS(3, dimension->getMaximum()); TS_ASSERT_EQUALS(8, dimension->getNBins()); - delete dimension; } void testCorrectGenerationWithoutUnits() { - using namespace Mantid::Geometry; - IMDDimensionFactory factory(constructDimensionWithoutUnits()); - IMDDimension* dimension = factory.create(); + IMDDimension_const_sptr dimension = IMDDimensionFactory::create(constructDimensionWithoutUnits()); TS_ASSERT_EQUALS("None", dimension->getUnits()); TS_ASSERT_EQUALS("Qz", dimension->getName()); TS_ASSERT_EQUALS("qz", dimension->getDimensionId()); TS_ASSERT_EQUALS(-3, dimension->getMinimum()); TS_ASSERT_EQUALS(3, dimension->getMaximum()); TS_ASSERT_EQUALS(8, dimension->getNBins()); - delete dimension; } void testStaticCreation() { std::string xmlToParse = constructNonReciprocalDimensionXMLString(); - - IMDDimensionFactory factoryA = IMDDimensionFactory::createDimensionFactory(xmlToParse); - IMDDimensionFactory factoryB(constructNonReciprocalDimensionXML()); + IMDDimension_const_sptr viaString = IMDDimensionFactory::create(xmlToParse); + auto document = constructNonReciprocalDimensionXML(); + IMDDimension_const_sptr viaXML = IMDDimensionFactory::create(document->documentElement()); //Constructed either way, the products should be equivalent - TSM_ASSERT_EQUALS("Created through either route, the products should be equal", factoryA.create()->getDimensionId(), factoryB.create()->getDimensionId()); + TSM_ASSERT_EQUALS("Created through either route, the products should be equal", viaString->getDimensionId(), viaXML->getDimensionId()); } }; From 6229cdfcd13b7f77fbce21676babd7cde361b247 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Tue, 4 Mar 2014 15:30:51 -0500 Subject: [PATCH 088/118] Re #9118. Remove unused inclusions of IMDDimensionFactory. --- .../MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx | 1 - .../RebinningTransformOperator/vtkRebinningTransformOperator.cxx | 1 - Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx index ca1f02185685..62744484d5ce 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx @@ -16,7 +16,6 @@ #include "MantidKernel/Exception.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include "MantidVatesAPI/EscalatingRebinningActionManager.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx index 827c7416f818..acb764342886 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx @@ -15,7 +15,6 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidVatesAPI/ADSWorkspaceProvider.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" -#include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include "MantidVatesAPI/EscalatingRebinningActionManager.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" #include "MantidVatesAPI/vtkMDQuadFactory.h" diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp index 089ebc20d893..38c18916e0f1 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp @@ -1,7 +1,6 @@ #include "MantidVatesAPI/vtkDataSetToGeometry.h" #include "MantidVatesAPI/FieldDataToMetadata.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" -#include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include "vtkDataSet.h" From afb838529789bc391ff6f00cb2fe97b669ce17be Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Tue, 4 Mar 2014 16:58:42 -0500 Subject: [PATCH 089/118] Re #9118. Refactor and greatly simplify IMDDimensionFactory. It's no longer a class, just 3 non-member functions that create an IMDDimension object (actually an MDHistoDimension object, as before) given an input XML string or a Poco::XML::Element. It no longer retains ownership of any Poco::XML object, which will allow me to handle the previously unreleased memory issues. --- .../MDGeometry/IMDDimensionFactory.h | 101 ++++--------- .../src/MDGeometry/IMDDimensionFactory.cpp | 142 ++++-------------- .../src/MDGeometry/MDGeometryXMLParser.cpp | 4 +- .../Geometry/test/IMDDimensionFactoryTest.h | 20 ++- .../Framework/MDAlgorithms/src/LoadMD.cpp | 4 +- 5 files changed, 72 insertions(+), 199 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimensionFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimensionFactory.h index 90465c837e99..8fbbb1d409f0 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimensionFactory.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimensionFactory.h @@ -1,42 +1,13 @@ #ifndef IMDDIMENSIONFACTORY_H_ #define IMDDIMENSIONFACTORY_H_ -/** -* IMDDimensionFactory. Handles conversion of dimension xml to IMDDimension objects. -* -* This algorithm performs dynamic rebinning driven by the xml string passed as an input. -* -* @date 10/02/2011 -* @author Owen Arnold -* -* Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory -* -* This file is part of Mantid. -* -* Mantid is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. -* -* Mantid is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* File change history is stored at: -* Code Documentation is available at: -*/ - #include "MantidGeometry/MDGeometry/IMDDimension.h" namespace Poco { namespace XML { -class Element; + class Element; } } @@ -44,50 +15,32 @@ namespace Mantid { namespace Geometry { -class MDHistoDimension; -class MANTID_GEOMETRY_DLL IMDDimensionFactory -{ - -public: - - /// Constructor - IMDDimensionFactory(Poco::XML::Element* dimensionXML); - - /// Constructor - IMDDimensionFactory(const IMDDimensionFactory& other); - - /// Assignment operator - IMDDimensionFactory& operator=(const IMDDimensionFactory& other); - - /// Alternate Constructional method. - static IMDDimensionFactory createDimensionFactory(const std::string& xmlString); - - /// Destructor - ~IMDDimensionFactory(); - - /// Factory method. - IMDDimension* create() const; - - /// Factory method. - IMDDimension* create(int nBins, double min, double max) const; - -private: - - IMDDimensionFactory(); - - void setXMLString(const std::string& xmlString); - - /// Internal creation method. - MDHistoDimension* doCreate() const; - - /// Dimension xml to process. - Poco::XML::Element* m_dimensionXML; -}; - - -MANTID_GEOMETRY_DLL Mantid::Geometry::IMDDimension_sptr createDimension(const std::string& dimensionXMLString); - -MANTID_GEOMETRY_DLL Mantid::Geometry::IMDDimension_sptr createDimension(const std::string& dimensionXMLString, int nBins, double min, double max); +/** Creates IMDDimension objects based on input XML. + * + * Copyright © 2010-2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + * + * This file is part of Mantid. + * + * Mantid is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Mantid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * File change history is stored at: + * Code Documentation is available at: + */ + +MANTID_GEOMETRY_DLL IMDDimension_sptr createDimension(const std::string& dimensionXMLString); +MANTID_GEOMETRY_DLL IMDDimension_sptr createDimension(const Poco::XML::Element& dimensionXML); +MANTID_GEOMETRY_DLL IMDDimension_sptr createDimension(const std::string& dimensionXMLString, int nBins, coord_t min, coord_t max); } } diff --git a/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp b/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp index 2a12ec3c7536..1b3a3a3d0b35 100644 --- a/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp @@ -1,120 +1,47 @@ #include #include #include -#include #include +#include +#include #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" -#include -#include - namespace Mantid { namespace Geometry { -IMDDimensionFactory IMDDimensionFactory::createDimensionFactory(const std::string& dimensionXMLString) -{ - //Exception safe usage. - IMDDimensionFactory factory; - factory.setXMLString(dimensionXMLString); - return factory; -} - -IMDDimensionFactory::IMDDimensionFactory(Poco::XML::Element* dimensionXML) : - m_dimensionXML(dimensionXML) -{ -} - -IMDDimensionFactory::IMDDimensionFactory(const IMDDimensionFactory& other) : m_dimensionXML(other.m_dimensionXML) -{ -} - - -IMDDimensionFactory& IMDDimensionFactory::operator=(const IMDDimensionFactory& other) -{ - if(&other != this) - { - m_dimensionXML = other.m_dimensionXML; - } - return *this; -} - -/// Constructor -IMDDimensionFactory::IMDDimensionFactory() : m_dimensionXML(NULL) -{ -} - -/// Destructor -IMDDimensionFactory::~IMDDimensionFactory() -{ -} - -/**Set the xml string from which the dimension will be generated. - @param dimensionXMLString : xml string to generate the dimension from. -*/ -void IMDDimensionFactory::setXMLString(const std::string& dimensionXMLString) +/// Create a dimension object from the provided XML string. +IMDDimension_sptr createDimension(const std::string& dimensionXMLString) { Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(dimensionXMLString); - Poco::XML::Element* pDimensionElement = pDoc->documentElement(); - m_dimensionXML = pDimensionElement; -} - - -/**Creation method of factory using xml as-is. - @return IMDDimension generated. -*/ -Mantid::Geometry::IMDDimension* IMDDimensionFactory::create() const -{ - return doCreate(); -} - - -/**Creation method of factory using xml with overrides. - @param nBins : overrriden number of bins - @param min : overriden minimum - @param max : overriden maximum - @return IMDDimension generated. -*/ -Mantid::Geometry::IMDDimension* IMDDimensionFactory::create(int nBins, double min, double max) const -{ - MDHistoDimension* product = doCreate(); - product->setRange(nBins, static_cast(min), static_cast(max)); //Override the number of bins, min and max. - return product; + Poco::AutoPtr pDoc = pParser.parseString(dimensionXMLString); + return createDimension(*pDoc->documentElement()); } -/** Create the dimension as a MDHistogram dimension. -*/ -Mantid::Geometry::MDHistoDimension* IMDDimensionFactory::doCreate() const +/// Create a dimension from the provided XML element. +IMDDimension_sptr createDimension(const Poco::XML::Element& dimensionXML) { - using namespace Mantid::Geometry; - - if(m_dimensionXML == NULL) - { - throw std::runtime_error("Must provide dimension xml before creation"); - } - - Poco::XML::NamedNodeMap* attributes = m_dimensionXML->attributes(); + Poco::AutoPtr attributes = dimensionXML.attributes(); //First and only attribute is the dimension id. Poco::XML::Node* dimensionId = attributes->item(0); std::string id = dimensionId->innerText(); - std::string name = m_dimensionXML->getChildElement("Name")->innerText(); - Poco::XML::Element* unitsElement = m_dimensionXML->getChildElement("Units"); + std::string name = dimensionXML.getChildElement("Name")->innerText(); + Poco::XML::Element* unitsElement = dimensionXML.getChildElement("Units"); std::string units = "None"; if(NULL != unitsElement) { //Set units if they exist. units = unitsElement->innerText(); } - double upperBounds = atof(m_dimensionXML->getChildElement("UpperBounds")->innerText().c_str()); - double lowerBounds = atof(m_dimensionXML->getChildElement("LowerBounds")->innerText().c_str()); - unsigned int nBins = atoi(m_dimensionXML->getChildElement("NumberOfBins")->innerText().c_str()); - Poco::XML::Element* integrationXML = m_dimensionXML->getChildElement("Integrated"); + double upperBounds = atof(dimensionXML.getChildElement("UpperBounds")->innerText().c_str()); + double lowerBounds = atof(dimensionXML.getChildElement("LowerBounds")->innerText().c_str()); + unsigned int nBins = atoi(dimensionXML.getChildElement("NumberOfBins")->innerText().c_str()); + Poco::XML::Element* integrationXML = dimensionXML.getChildElement("Integrated"); if (NULL != integrationXML) { @@ -126,35 +53,22 @@ Mantid::Geometry::MDHistoDimension* IMDDimensionFactory::doCreate() const lowerBounds = lowerLimit; } - return new MDHistoDimension(name, id, units, static_cast(lowerBounds), static_cast(upperBounds), nBins); + return boost::make_shared(name, id, units, static_cast(lowerBounds), static_cast(upperBounds), nBins); } -/** - Convenience service non-member function. Hides use of factory. Creates IMDDimension. - @param dimensionXMLString :: Dimension xml. - @return new IMDDimension in a shared pointer. - */ -Mantid::Geometry::IMDDimension_sptr createDimension(const std::string& dimensionXMLString) - { - IMDDimensionFactory factory = IMDDimensionFactory::createDimensionFactory(dimensionXMLString); - return IMDDimension_sptr(factory.create()); - } - - -/** - Convenience service non-member function. Hides use of factory. Creates IMDDimension. Also sets min max and number of bins on the dimension. - @param dimensionXMLString :: Dimension xml. - @param nBins :: Number of bins. - @param min :: Minimum - @param max :: Maximum - @return new IMDDimension in a shared pointer. +/** Create a dimension object from the provided XML string, overriding certain attributes. + * @param dimensionXMLString The XML string from which to construct the dimension object. + * @param nBins The number of bins to set on the dimension object. + * @param min The minimum extent to set on the dimension. + * @param max The maximum extent to set on the dimension. + * @return The created dimension. */ - Mantid::Geometry::IMDDimension_sptr createDimension(const std::string& dimensionXMLString, int nBins, double min, double max) - { - IMDDimensionFactory factory = IMDDimensionFactory::createDimensionFactory(dimensionXMLString); - return IMDDimension_sptr(factory.create(nBins, min, max)); - } - +IMDDimension_sptr createDimension(const std::string& dimensionXMLString, int nBins, coord_t min, coord_t max) +{ + auto dimension = createDimension(dimensionXMLString); + dimension->setRange(nBins,min,max); + return dimension; +} } // namespace } // namespace diff --git a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp index 24ee1b4ab13d..22b5ebac17e0 100644 --- a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp @@ -87,9 +87,7 @@ namespace Mantid for (size_t i = 0; i < nDimensions; i++) { Poco::XML::Element* dimensionXML = static_cast (dimensionsXML->item(static_cast(i))); - Mantid::Geometry::IMDDimensionFactory factory(dimensionXML); - Mantid::Geometry::IMDDimension* dimension = factory.create(); - vecAllDims[i] = boost::shared_ptr(dimension); + vecAllDims[i] = createDimension(*dimensionXML); } VecIMDDimension_sptr vecNonMappedDims = vecAllDims; Poco::XML::Element* xDimensionElement = geometryXMLElement->getChildElement(MDGeometryXMLDefinitions::workspaceXDimensionElementName()); diff --git a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h index 4280a12d7e9c..9cda46643b00 100644 --- a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h @@ -52,7 +52,7 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite void testCorrectGeneration() { - IMDDimension_const_sptr dimension = IMDDimensionFactory::create(constructDimensionWithUnitsXMLString()); + IMDDimension_const_sptr dimension = createDimension(constructDimensionWithUnitsXMLString()); TS_ASSERT_EQUALS("Cubits", dimension->getUnits()); TS_ASSERT_EQUALS("Qz", dimension->getName()); TS_ASSERT_EQUALS("qz", dimension->getDimensionId()); @@ -63,7 +63,7 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite void testCorrectGenerationWithoutUnits() { - IMDDimension_const_sptr dimension = IMDDimensionFactory::create(constructDimensionWithoutUnits()); + IMDDimension_const_sptr dimension = createDimension(constructDimensionWithoutUnitsXMLString()); TS_ASSERT_EQUALS("None", dimension->getUnits()); TS_ASSERT_EQUALS("Qz", dimension->getName()); TS_ASSERT_EQUALS("qz", dimension->getDimensionId()); @@ -72,16 +72,26 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite TS_ASSERT_EQUALS(8, dimension->getNBins()); } - void testStaticCreation() + void testCreationViaStringVsElement() { std::string xmlToParse = constructNonReciprocalDimensionXMLString(); - IMDDimension_const_sptr viaString = IMDDimensionFactory::create(xmlToParse); + IMDDimension_const_sptr viaString = createDimension(xmlToParse); auto document = constructNonReciprocalDimensionXML(); - IMDDimension_const_sptr viaXML = IMDDimensionFactory::create(document->documentElement()); + IMDDimension_const_sptr viaXML = createDimension(*document->documentElement()); //Constructed either way, the products should be equivalent TSM_ASSERT_EQUALS("Created through either route, the products should be equal", viaString->getDimensionId(), viaXML->getDimensionId()); + } + void testOverrideMethod() + { + IMDDimension_const_sptr dimension = createDimension(constructDimensionWithUnitsXMLString(),10,-9.0,8.5); + TS_ASSERT_EQUALS("Cubits", dimension->getUnits()); + TS_ASSERT_EQUALS("Qz", dimension->getName()); + TS_ASSERT_EQUALS("qz", dimension->getDimensionId()); + TS_ASSERT_EQUALS(-9.0, dimension->getMinimum()); + TS_ASSERT_EQUALS(8.5, dimension->getMaximum()); + TS_ASSERT_EQUALS(10, dimension->getNBins()); } }; #endif diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp index a41c27afced0..8b081b39ea0d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp @@ -286,9 +286,7 @@ namespace Mantid std::string dimXML; m_file->getAttr(mess.str(), dimXML); // Use the dimension factory to read the XML - IMDDimensionFactory factory = IMDDimensionFactory::createDimensionFactory(dimXML); - IMDDimension_sptr dim(factory.create()); - m_dims.push_back(dim); + m_dims.push_back(createDimension(dimXML)); } } From fe189e17487c4e3a17a12438ad590f0f23c4a952 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Wed, 5 Mar 2014 09:52:25 +0000 Subject: [PATCH 090/118] Refs #9120. Process events after the search is finished After the file searching thread is finished, it emits some signals which MWRunFiles needs to process before we can access the found files. We are now doing that by calling QApplication::processEvent() after the search process has finished. --- .../MantidQt/MantidWidgets/src/MuonSequentialFitDialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/MuonSequentialFitDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/MuonSequentialFitDialog.cpp index 6d131db2d242..b67b6075a9e8 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/MuonSequentialFitDialog.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/MuonSequentialFitDialog.cpp @@ -297,9 +297,12 @@ namespace MantidWidgets // Wait for file search to finish. while ( m_ui.runs->isSearching() ) { - QApplication::instance()->processEvents(); + QApplication::processEvents(); } + // To process events from the finished thread + QApplication::processEvents(); + // Validate input fields if ( ! isInputValid() ) { From d9c1ee1533322ae0538c3fdb96f491cf571ef3cb Mon Sep 17 00:00:00 2001 From: Anders Markvardsen Date: Wed, 5 Mar 2014 12:45:50 +0000 Subject: [PATCH 091/118] Torben changed code to load new mcstas format. re #9114 --- .../Framework/DataHandling/src/LoadMcStas.cpp | 5 ++++- Test/AutoTestData/mcstas_event_hist.h5 | Bin 237853 -> 226463 bytes 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp index 9bbcd0186ca5..4a336a430d5a 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp @@ -123,6 +123,9 @@ namespace DataHandling */ void LoadMcStas::exec() { + + + std::string filename = getPropertyValue("Filename"); g_log.debug() << "Opening file " << filename << std::endl; @@ -556,7 +559,7 @@ namespace DataHandling file.openGroup("simulation", "NXnote"); std::string nameAttrValue; file.readData("name", nameAttrValue); - if(boost::iequals(nameAttrValue, "mcstas")) confidence = 98; + if(boost::iequals(nameAttrValue, "mccode")) confidence = 98; file.closeGroup(); file.closeGroup(); } diff --git a/Test/AutoTestData/mcstas_event_hist.h5 b/Test/AutoTestData/mcstas_event_hist.h5 index dd9c0ac3a91f5714f45d7e89b8988d6987a44cbb..f323eca5a4d32c21c411986c67f665c661d10014 100644 GIT binary patch literal 226463 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 z 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

*9hcW0Dwr{O6FbLKq>whss6 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 literal 237853 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�fsXlsXAjfF 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 Date: Wed, 5 Mar 2014 14:07:34 +0000 Subject: [PATCH 092/118] Revert to const reference. Refs #9084. - Passing by value does not work on windows when setting the endpoint inside `setICATProxySettings` in `ICat4Catalog`. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h | 6 +++--- Code/Mantid/Framework/API/src/CatalogSession.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h index 85d616717a35..23087f80f0da 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogSession.h @@ -38,10 +38,10 @@ namespace Mantid { public: CatalogSession(const std::string &sessionID, const std::string &facility, const std::string &endpoint); - std::string getSessionId() const; + const std::string& getSessionId() const; void setSessionId(const std::string &sessionID); - std::string getSoapEndpoint() const; - std::string getFacility() const; + const std::string& getSoapEndpoint() const; + const std::string& getFacility() const; private: std::string m_sessionID; diff --git a/Code/Mantid/Framework/API/src/CatalogSession.cpp b/Code/Mantid/Framework/API/src/CatalogSession.cpp index 2218e022d0e9..9b7b92881a6d 100644 --- a/Code/Mantid/Framework/API/src/CatalogSession.cpp +++ b/Code/Mantid/Framework/API/src/CatalogSession.cpp @@ -18,7 +18,7 @@ namespace Mantid * Obtain the session ID for the catalog created. * @return The sesssion Id of the catalog created. */ - std::string CatalogSession::getSessionId() const + const std::string& CatalogSession::getSessionId() const { return m_sessionID; } @@ -36,7 +36,7 @@ namespace Mantid * Obtains the soap end-point of the catalog created. * @return The soap end-point used to create the catalog. */ - std::string CatalogSession::getSoapEndpoint() const + const std::string& CatalogSession::getSoapEndpoint() const { return m_endpoint; } @@ -45,7 +45,7 @@ namespace Mantid * Obtain the facility of the catalog created. * @return The facility used to create the catalog. */ - std::string CatalogSession::getFacility() const + const std::string& CatalogSession::getFacility() const { return m_facility; } From d5ef042b43de8cb37b22fc3c79a7acca6552af83 Mon Sep 17 00:00:00 2001 From: Jay Rainey Date: Wed, 5 Mar 2014 14:26:44 +0000 Subject: [PATCH 093/118] Fix download and upload on windows. Refs #9084. --- Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h | 4 ++-- Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h | 4 ++-- .../MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h index 807aecdb61e5..43876ecedea0 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogFactory.h @@ -89,9 +89,9 @@ namespace Mantid template class MANTID_API_DLL Mantid::Kernel::SingletonHolder; #endif /* _WIN32 */ /// The specialisation of the SingletonHolder class that holds the CatalogFactory - typedef Mantid::Kernel::SingletonHolder CatalogFactory; + typedef MANTID_API_DLL Mantid::Kernel::SingletonHolder CatalogFactory; } // namespace API } // namespace Mantid -#endif /*MANTID_API_CatalogFACTORYIMPL_H_*/ +#endif /*MANTID_API_CATALOGFACTORYIMPL_H_*/ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h index 726a1c5e2d5b..472b8307ff16 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/CatalogManager.h @@ -59,9 +59,9 @@ namespace Mantid }; #ifdef _WIN32 - template class DLLExport Kernel::SingletonHolder; + template class MANTID_API_DLL Kernel::SingletonHolder; #endif - typedef Kernel::SingletonHolder CatalogManager; + typedef MANTID_API_DLL Kernel::SingletonHolder CatalogManager; } } diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp index f238da738d5d..4fcfaf06ef3f 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/CatalogPublishDialog.cpp @@ -61,10 +61,10 @@ namespace MantidQt void CatalogPublishDialog::populateUserInvestigations() { auto workspace = Mantid::API::WorkspaceFactory::Instance().createTable(); + // This again is a temporary measure to ensure publishing functionality will work with one catalog. auto session = Mantid::API::CatalogManager::Instance().getActiveSessions(); - if (!session.empty()) - Mantid::API::CatalogManager::Instance().getCatalog(session.front()->getSessionId())->myData(workspace); + if (!session.empty()) Mantid::API::CatalogManager::Instance().getCatalog(session.front()->getSessionId())->myData(workspace); // The user is not an investigator on any investigations and cannot publish // or they are not logged into the catalog then update the related message.. From 539299601b8efc31411c6b8e398b0cf8d8054c75 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Wed, 5 Mar 2014 13:40:45 -0500 Subject: [PATCH 094/118] Re #9118. Fix narrowing conversion compiler warning the long way. Rather than resorting to a static_cast, it seems like the method over on the VATES side should be returning a coord_t (float) to align it with the IMDDimension that it relates to. --- .../Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h | 4 +++- .../ParaViewWidgets/QtWidgets/DimensionWidget.cpp | 8 ++++---- .../ParaViewWidgets/QtWidgets/DimensionWidget.h | 4 ++-- .../Vates/VatesAPI/inc/MantidVatesAPI/DimensionView.h | 5 +++-- Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h index be0c3e9803c6..532fa6905669 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h @@ -69,7 +69,9 @@ namespace Mantid /// @return an XML string representation of the dimension. virtual std::string toXMLString() const = 0; - /// Change the extents and number of bins + /** Change the extents and number of bins + * @throws std::invalid_argument If min is greater than max + */ virtual void setRange(size_t nBins, coord_t min, coord_t max) = 0; /** @return coordinate of the axis at the given index diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.cpp b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.cpp index 019cba7ef85f..224b9bd990ca 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.cpp +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.cpp @@ -115,14 +115,14 @@ BinInputWidget* DimensionWidget::getCurrentBinInputWidget() const return dynamic_cast(w); } -double DimensionWidget::getMinimum() const +Mantid::coord_t DimensionWidget::getMinimum() const { - return atof(m_minBox->text().toStdString().c_str()); + return m_minBox->text().toFloat(); } -double DimensionWidget::getMaximum() const +Mantid::coord_t DimensionWidget::getMaximum() const { - return atof(m_maxBox->text().toStdString().c_str()); + return m_maxBox->text().toFloat(); } unsigned int DimensionWidget::getNBins() const diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.h index 69b2334e8aa7..9d707e0873ce 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/DimensionWidget.h @@ -50,10 +50,10 @@ Q_OBJECT ~DimensionWidget(); /// Get minimum - double getMinimum() const; + Mantid::coord_t getMinimum() const; /// Get maximum - double getMaximum() const; + Mantid::coord_t getMaximum() const; signals: diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/DimensionView.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/DimensionView.h index 40fdd2a42141..e068c5472a63 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/DimensionView.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/DimensionView.h @@ -2,6 +2,7 @@ #define DIMENSION_VIEW_H_ #include "MantidKernel/System.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" + namespace Mantid { namespace VATES @@ -26,8 +27,8 @@ namespace Mantid virtual void displayError(std::string message) const = 0; virtual void accept(DimensionPresenter* pDimensionPresenter) = 0; //TODO should accept non-deleting unique pointer. virtual std::string getVisDimensionName() const = 0; - virtual double getMaximum() const = 0; - virtual double getMinimum() const = 0; + virtual coord_t getMaximum() const = 0; + virtual coord_t getMinimum() const = 0; virtual unsigned int getNBins() const = 0; virtual unsigned int getSelectedIndex() const = 0; virtual bool getIsIntegrated() const = 0; diff --git a/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp index 189b9e86ef3d..25c10bb0f0fa 100644 --- a/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/DimensionPresenter.cpp @@ -126,8 +126,8 @@ namespace Mantid nbins = 1; } - double min = m_view->getMinimum(); - double max = m_view->getMaximum(); + auto min = m_view->getMinimum(); + auto max = m_view->getMaximum(); try { return Mantid::Geometry::createDimension(m_model->toXMLString(), nbins, min, max); From 77ad2bf1d2dddd3ddf961a7601d9530f35edd5e4 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Wed, 5 Mar 2014 14:15:44 -0500 Subject: [PATCH 095/118] Re #9118. Correct tests to fix builds. --- Code/Mantid/Vates/VatesAPI/test/DimensionPresenterTest.h | 4 ++-- .../Vates/VatesAPI/test/SynchronisingGeometryPresenterTest.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/Vates/VatesAPI/test/DimensionPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/DimensionPresenterTest.h index 48247df2e9ca..4c7aff2fc687 100644 --- a/Code/Mantid/Vates/VatesAPI/test/DimensionPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/DimensionPresenterTest.h @@ -26,8 +26,8 @@ class DimensionPresenterTest: public CxxTest::TestSuite MOCK_METHOD1(showAsNotIntegrated, void(VecIMDDimension_sptr)); MOCK_METHOD0(showAsIntegrated, void()); MOCK_METHOD1(accept, void(DimensionPresenter*)); - MOCK_CONST_METHOD0(getMinimum, double()); - MOCK_CONST_METHOD0(getMaximum, double()); + MOCK_CONST_METHOD0(getMinimum, float()); + MOCK_CONST_METHOD0(getMaximum, float()); MOCK_CONST_METHOD0(getNBins, unsigned int()); MOCK_CONST_METHOD0(getSelectedIndex, unsigned int()); MOCK_CONST_METHOD0(getIsIntegrated, bool()); diff --git a/Code/Mantid/Vates/VatesAPI/test/SynchronisingGeometryPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/SynchronisingGeometryPresenterTest.h index ac54499c2321..407be0a2676f 100644 --- a/Code/Mantid/Vates/VatesAPI/test/SynchronisingGeometryPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/SynchronisingGeometryPresenterTest.h @@ -103,8 +103,8 @@ static std::string constructXML(std::string nbinsA, std::string nbinsB, std::str MOCK_METHOD0(showAsIntegrated, void()); MOCK_METHOD1(accept, void(DimensionPresenter*)); MOCK_CONST_METHOD0(getVisDimensionName, std::string()); - MOCK_CONST_METHOD0(getMinimum, double()); - MOCK_CONST_METHOD0(getMaximum, double()); + MOCK_CONST_METHOD0(getMinimum, float()); + MOCK_CONST_METHOD0(getMaximum, float()); MOCK_CONST_METHOD0(getNBins, unsigned int()); MOCK_CONST_METHOD0(getSelectedIndex, unsigned int()); MOCK_CONST_METHOD0(getIsIntegrated, bool()); From 84af34a7bb6fa19b7f37e23ec37fba64dde6ff87 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Wed, 5 Mar 2014 17:14:29 -0500 Subject: [PATCH 096/118] Re #9118. Protect against malformed XML. I added a bunch of tests for the XML string not being as expected and then refactored the code to protect against that. --- .../src/MDGeometry/IMDDimensionFactory.cpp | 74 ++++++++++++++++--- .../Geometry/test/IMDDimensionFactoryTest.h | 28 +++++++ 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp b/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp index 1b3a3a3d0b35..ed683c32eca1 100644 --- a/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/MDGeometry/IMDDimensionFactory.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include +#include #include #include "MantidGeometry/MDGeometry/MDHistoDimension.h" @@ -13,11 +15,22 @@ namespace Mantid namespace Geometry { -/// Create a dimension object from the provided XML string. +/** Create a dimension object from the provided XML string. + * @param dimensionXMLString The XML string + * @throw Poco::XML::SAXParseException If the provided string is not valid XML + * @return The created dimension. + */ IMDDimension_sptr createDimension(const std::string& dimensionXMLString) { Poco::XML::DOMParser pParser; - Poco::AutoPtr pDoc = pParser.parseString(dimensionXMLString); + Poco::AutoPtr pDoc; + try { + pDoc = pParser.parseString(dimensionXMLString); + + } catch (Poco::XML::XMLException& ex) { + // Transform into std::invalid_argument + throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what()); + } return createDimension(*pDoc->documentElement()); } @@ -27,23 +40,62 @@ IMDDimension_sptr createDimension(const Poco::XML::Element& dimensionXML) Poco::AutoPtr attributes = dimensionXML.attributes(); //First and only attribute is the dimension id. - Poco::XML::Node* dimensionId = attributes->item(0); - std::string id = dimensionId->innerText(); + //Poco::XML::Node* dimensionId = attributes->item(0); + const std::string id = dimensionXML.getAttribute("ID");// dimensionId->innerText(); + if ( id.empty() ) + { + throw std::invalid_argument("Invalid string passed to createDimension: No ID attribute"); + } + + Poco::XML::Element* nameElement = dimensionXML.getChildElement("Name"); + if ( NULL == nameElement ) + { + throw std::invalid_argument("Invalid string passed to createDimension: No Name element"); + } + const std::string name = nameElement->innerText(); - std::string name = dimensionXML.getChildElement("Name")->innerText(); Poco::XML::Element* unitsElement = dimensionXML.getChildElement("Units"); std::string units = "None"; - if(NULL != unitsElement) + if( NULL != unitsElement ) { //Set units if they exist. units = unitsElement->innerText(); } - double upperBounds = atof(dimensionXML.getChildElement("UpperBounds")->innerText().c_str()); - double lowerBounds = atof(dimensionXML.getChildElement("LowerBounds")->innerText().c_str()); - unsigned int nBins = atoi(dimensionXML.getChildElement("NumberOfBins")->innerText().c_str()); - Poco::XML::Element* integrationXML = dimensionXML.getChildElement("Integrated"); - if (NULL != integrationXML) + Poco::XML::Element* upperBoundsElement = dimensionXML.getChildElement("UpperBounds"); + if ( NULL == upperBoundsElement ) + { + throw std::invalid_argument("Invalid string passed to createDimension: No UpperBounds element"); + } + Poco::XML::Element* lowerBoundsElement = dimensionXML.getChildElement("LowerBounds"); + if ( NULL == lowerBoundsElement ) + { + throw std::invalid_argument("Invalid string passed to createDimension: No LowerBounds element"); + } + + double upperBounds, lowerBounds; + try { + upperBounds = Poco::NumberParser::parseFloat( upperBoundsElement->innerText() ); + lowerBounds = Poco::NumberParser::parseFloat( lowerBoundsElement->innerText() ); + } + catch (Poco::SyntaxException& ex) { + throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what() ); + } + + Poco::XML::Element* numBinsElement = dimensionXML.getChildElement("NumberOfBins"); + if ( NULL == numBinsElement ) + { + throw std::invalid_argument("Invalid string passed to createDimension: No NumberOfBins element"); + } + unsigned int nBins; + try { + nBins = Poco::NumberParser::parseUnsigned(numBinsElement->innerText()); + } catch (Poco::SyntaxException& ex) { + throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what() ); + } + + Poco::XML::Element* integrationXML = dimensionXML.getChildElement("Integrated"); + if ( NULL != integrationXML ) { double upperLimit = atof(integrationXML->getChildElement("UpperLimit")->innerText().c_str()); double lowerLimit = atof(integrationXML->getChildElement("LowerLimit")->innerText().c_str()); diff --git a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h index 9cda46643b00..0814d7590482 100644 --- a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h @@ -5,6 +5,7 @@ #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" #include #include +#include #include using namespace Mantid::Geometry; @@ -93,5 +94,32 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite TS_ASSERT_EQUALS(8.5, dimension->getMaximum()); TS_ASSERT_EQUALS(10, dimension->getNBins()); } + + void testPassInvalidString() + { + TS_ASSERT_THROWS( createDimension(""), std::invalid_argument ); + TS_ASSERT_THROWS( createDimension("garbage"), std::invalid_argument ); + + std::string xmlString = constructNonReciprocalDimensionXMLString(); + xmlString.erase(96,30); + std::cout << xmlString << std::endl; + + std::string missingID = constructNonReciprocalDimensionXMLString().erase(10,8); + TS_ASSERT_THROWS( createDimension(missingID), std::invalid_argument ); + std::string missingName = constructNonReciprocalDimensionXMLString().erase(19,19); + TS_ASSERT_THROWS( createDimension(missingName), std::invalid_argument ); + std::string missingUpperBounds = constructNonReciprocalDimensionXMLString().erase(38,30); + TS_ASSERT_THROWS( createDimension(missingUpperBounds), std::invalid_argument ); + std::string missingUpperBoundsValue = constructNonReciprocalDimensionXMLString().erase(51,3); + TS_ASSERT_THROWS( createDimension(missingUpperBoundsValue), std::invalid_argument ); + std::string missingLowerBounds = constructNonReciprocalDimensionXMLString().erase(68,28); + TS_ASSERT_THROWS( createDimension(missingLowerBounds), std::invalid_argument ); + std::string missingLowerBoundsValue = constructNonReciprocalDimensionXMLString().erase(81,1); + TS_ASSERT_THROWS( createDimension(missingLowerBoundsValue), std::invalid_argument ); + std::string missingNumberOfBins = constructNonReciprocalDimensionXMLString().erase(96,30); + TS_ASSERT_THROWS( createDimension(missingNumberOfBins), std::invalid_argument ); + std::string missingNumberOfBinsValue = constructNonReciprocalDimensionXMLString().erase(110,1); + TS_ASSERT_THROWS( createDimension(missingNumberOfBins), std::invalid_argument ); + } }; #endif From 8f4357425f0f60481e782c7ad813ecba76dd9fe6 Mon Sep 17 00:00:00 2001 From: Anders Markvardsen Date: Thu, 6 Mar 2014 14:02:14 +0000 Subject: [PATCH 097/118] Added progress reporting. re #9116 Also changed as tabs to white spaces --- .../Framework/DataHandling/src/LoadMcStas.cpp | 862 +++++++++--------- 1 file changed, 435 insertions(+), 427 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp index 4a336a430d5a..1dd72609f638 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMcStas.cpp @@ -63,320 +63,328 @@ namespace Mantid { namespace DataHandling { - using namespace Kernel; - using namespace API; - using namespace DataObjects; + using namespace Kernel; + using namespace API; + using namespace DataObjects; - // Register the algorithm into the AlgorithmFactory - DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStas); + // Register the algorithm into the AlgorithmFactory + DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMcStas); - //---------------------------------------------------------------------------------------------- - /** Constructor - */ + //---------------------------------------------------------------------------------------------- + /** Constructor + */ LoadMcStas::LoadMcStas() : m_countNumWorkspaceAdded(1) { } - //---------------------------------------------------------------------------------------------- - /** Destructor - */ - LoadMcStas::~LoadMcStas() - { - } + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + LoadMcStas::~LoadMcStas() + { + } - //---------------------------------------------------------------------------------------------- - // Algorithm's name for identification. @see Algorithm::name - const std::string LoadMcStas::name() const { return "LoadMcStas";}; + //---------------------------------------------------------------------------------------------- + // Algorithm's name for identification. @see Algorithm::name + const std::string LoadMcStas::name() const { return "LoadMcStas";}; - // Algorithm's version for identification. @see Algorithm::version - int LoadMcStas::version() const { return 1;}; + // Algorithm's version for identification. @see Algorithm::version + int LoadMcStas::version() const { return 1;}; - // Algorithm's category for identification. @see Algorithm::category - const std::string LoadMcStas::category() const { return "DataHandling";} - - //---------------------------------------------------------------------------------------------- - // Sets documentation strings for this algorithm - void LoadMcStas::initDocs() - { - this->setWikiSummary("This algorithm loads a McStas NeXus file into an workspace."); - this->setOptionalMessage("Loads a McStas NeXus file into an workspace."); - } - - //---------------------------------------------------------------------------------------------- - /** Initialize the algorithm's properties. - */ - void LoadMcStas::init() - { - std::vector exts; - exts.push_back(".h5"); - exts.push_back(".nxs"); - declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), "The name of the Nexus file to load" ); - - declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "An output workspace."); - } - - - //---------------------------------------------------------------------------------------------- - /** Execute the algorithm. - */ - void LoadMcStas::exec() - { - - - - std::string filename = getPropertyValue("Filename"); - g_log.debug() << "Opening file " << filename << std::endl; + // Algorithm's category for identification. @see Algorithm::category + const std::string LoadMcStas::category() const { return "DataHandling";} + + //---------------------------------------------------------------------------------------------- + // Sets documentation strings for this algorithm + void LoadMcStas::initDocs() + { + this->setWikiSummary("This algorithm loads a McStas NeXus file into an workspace."); + this->setOptionalMessage("Loads a McStas NeXus file into an workspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void LoadMcStas::init() + { + std::vector exts; + exts.push_back(".h5"); + exts.push_back(".nxs"); + declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), "The name of the Nexus file to load" ); + + declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "An output workspace."); + } + + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void LoadMcStas::exec() + { + + + + std::string filename = getPropertyValue("Filename"); + g_log.debug() << "Opening file " << filename << std::endl; - ::NeXus::File nxFile(filename); - auto entries = nxFile.getEntries(); - auto itend = entries.end(); - WorkspaceGroup_sptr outputGroup(new WorkspaceGroup); - - - // here loop over all top level Nexus entries - // HOWEVER IF IT IS KNOWN THAT MCSTAS NEXUS ONLY EVER HAVE ONE TOP LEVEL ENTRY - // THIS LOOP CAN BE REMOVED - for(auto it = entries.begin(); it != itend; ++it) - { - std::string name = it->first; - std::string type = it->second; - - // open top entry - open data entry - nxFile.openGroup(name, type); - nxFile.openGroup("data", "NXdetector"); - - auto dataEntries = nxFile.getEntries(); - - std::map eventEntries; - std::map histogramEntries; - - // populate eventEntries and histogramEntries - for(auto eit = dataEntries.begin(); eit != dataEntries.end(); ++eit) - { - std::string dataName = eit->first; - std::string dataType = eit->second; - if( dataName == "content_nxs" || dataType != "NXdata" ) continue; // can be removed if sure no Nexus files contains "content_nxs" - g_log.debug() << "Opening " << dataName << " " << dataType << std::endl; - - // open second level entry - nxFile.openGroup(dataName, dataType); - - // Find the Neutron_ID tag from McStas event data - // Each event detector has the nexus attribute: - // @long_name = data ' Intensity Position Position Neutron_ID Velocity Time_Of_Flight Monitor (Square)' - // if Neutron_ID present we have event data - - auto nxdataEntries = nxFile.getEntries(); - - for(auto nit = nxdataEntries.begin(); nit != nxdataEntries.end(); ++nit) - { - if(nit->second == "NXparameters") continue; - nxFile.openData(nit->first); - if(nxFile.hasAttr("long_name") ) - { - std::string nameAttrValue; - nxFile.getAttr("long_name", nameAttrValue); - - if ( nameAttrValue.find("Neutron_ID") != std::string::npos ) - { - eventEntries[eit->first] = eit->second; - } - else - { - histogramEntries[eit->first] = eit->second; - } - } - nxFile.closeData(); - } - // close second entry - nxFile.closeGroup(); - } - - - if ( !eventEntries.empty() ) - { - readEventData(eventEntries, outputGroup, nxFile); - } + ::NeXus::File nxFile(filename); + auto entries = nxFile.getEntries(); + auto itend = entries.end(); + WorkspaceGroup_sptr outputGroup(new WorkspaceGroup); + + + // here loop over all top level Nexus entries + // HOWEVER IF IT IS KNOWN THAT MCSTAS NEXUS ONLY EVER HAVE ONE TOP LEVEL ENTRY + // THIS LOOP CAN BE REMOVED + for(auto it = entries.begin(); it != itend; ++it) + { + std::string name = it->first; + std::string type = it->second; + + // open top entry - open data entry + nxFile.openGroup(name, type); + nxFile.openGroup("data", "NXdetector"); + + auto dataEntries = nxFile.getEntries(); + + std::map eventEntries; + std::map histogramEntries; + + // populate eventEntries and histogramEntries + for(auto eit = dataEntries.begin(); eit != dataEntries.end(); ++eit) + { + std::string dataName = eit->first; + std::string dataType = eit->second; + if( dataName == "content_nxs" || dataType != "NXdata" ) continue; // can be removed if sure no Nexus files contains "content_nxs" + g_log.debug() << "Opening " << dataName << " " << dataType << std::endl; + + // open second level entry + nxFile.openGroup(dataName, dataType); + + // Find the Neutron_ID tag from McStas event data + // Each event detector has the nexus attribute: + // @long_name = data ' Intensity Position Position Neutron_ID Velocity Time_Of_Flight Monitor (Square)' + // if Neutron_ID present we have event data + + auto nxdataEntries = nxFile.getEntries(); + + for(auto nit = nxdataEntries.begin(); nit != nxdataEntries.end(); ++nit) + { + if(nit->second == "NXparameters") continue; + nxFile.openData(nit->first); + if(nxFile.hasAttr("long_name") ) + { + std::string nameAttrValue; + nxFile.getAttr("long_name", nameAttrValue); + + if ( nameAttrValue.find("Neutron_ID") != std::string::npos ) + { + eventEntries[eit->first] = eit->second; + } + else + { + histogramEntries[eit->first] = eit->second; + } + } + nxFile.closeData(); + } + // close second entry + nxFile.closeGroup(); + } - readHistogramData(histogramEntries, outputGroup, nxFile); - - // close top entery - nxFile.closeGroup(); // corresponds to nxFile.openGroup("data", "NXdetector"); - nxFile.closeGroup(); - - setProperty("OutputWorkspace", outputGroup); - } - } // LoadMcStas::exec() + + if ( !eventEntries.empty() ) + { + readEventData(eventEntries, outputGroup, nxFile); + } + + readHistogramData(histogramEntries, outputGroup, nxFile); + + // close top entery + nxFile.closeGroup(); // corresponds to nxFile.openGroup("data", "NXdetector"); + nxFile.closeGroup(); + + setProperty("OutputWorkspace", outputGroup); + } + } // LoadMcStas::exec() - /** - * Return the confidence with with this algorithm can load the file + /** + * Return the confidence with with this algorithm can load the file * @param eventEntries map of the file entries that have events * @param outputGroup pointer to the workspace group - * @param nxFile Reads data from inside first first top entry - */ - void LoadMcStas::readEventData(const std::map& eventEntries, WorkspaceGroup_sptr& outputGroup, ::NeXus::File& nxFile) - { - std::string filename = getPropertyValue("Filename"); - auto entries = nxFile.getEntries(); - - // will assume that each top level entry contain one mcstas - // generated IDF and any event data entries within this top level - // entry are data collected for that instrument - // This code for loading the instrument is for now adjusted code from - // ExperimentalInfo. - - // Close data folder and go back to top level. Then read and close the Instrument folder. - nxFile.closeGroup(); - - Geometry::Instrument_sptr instrument; + * @param nxFile Reads data from inside first first top entry + */ + void LoadMcStas::readEventData(const std::map& eventEntries, WorkspaceGroup_sptr& outputGroup, ::NeXus::File& nxFile) + { + std::string filename = getPropertyValue("Filename"); + auto entries = nxFile.getEntries(); + + // will assume that each top level entry contain one mcstas + // generated IDF and any event data entries within this top level + // entry are data collected for that instrument + // This code for loading the instrument is for now adjusted code from + // ExperimentalInfo. + + // Close data folder and go back to top level. Then read and close the Instrument folder. + nxFile.closeGroup(); + + Geometry::Instrument_sptr instrument; + + // Initialize progress reporting + int reports = 2; + const double progressFractionInitial = 0.1; + Progress progInitial(this,0.0,progressFractionInitial, reports); - try - { - nxFile.openGroup("instrument", "NXinstrument"); - std::string instrumentXML; - nxFile.openGroup("instrument_xml", "NXnote"); - nxFile.readData("data", instrumentXML ); - nxFile.closeGroup(); - nxFile.closeGroup(); - - Geometry::InstrumentDefinitionParser parser; - std::string instrumentName = "McStas"; - parser.initialize(filename, instrumentName, instrumentXML); - std::string instrumentNameMangled = parser.getMangledName(); - - // Check whether the instrument is already in the InstrumentDataService - if ( InstrumentDataService::Instance().doesExist(instrumentNameMangled) ) - { - // If it does, just use the one from the one stored there - instrument = InstrumentDataService::Instance().retrieve(instrumentNameMangled); - } - else - { - // Really create the instrument - instrument = parser.parseXML(NULL); - // Add to data service for later retrieval - InstrumentDataService::Instance().add(instrumentNameMangled, instrument); - } - } - catch(...) - { - // Loader should not stop if there is no IDF.xml - g_log.warning() <<"\nCould not find the instrument description in the Nexus file:" << filename << " Ignore evntdata from data file" << std::endl; - return; - } - - - // Finished reading Instrument. Then open new data folder again - nxFile.openGroup("data", "NXdetector"); - - // create and prepare an event workspace ready to receive the mcstas events - EventWorkspace_sptr eventWS(new EventWorkspace()); - // initialize, where create up front number of eventlists = number of detectors - eventWS->initialize(instrument->getNumberDetectors(),1,1); - // Set the units - eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); - eventWS->setYUnit("Counts"); - // set the instrument - eventWS->setInstrument(instrument); - // assign detector ID to eventlists - - std::vector detIDs = instrument->getDetectorIDs(); + try + { + nxFile.openGroup("instrument", "NXinstrument"); + std::string instrumentXML; + nxFile.openGroup("instrument_xml", "NXnote"); + nxFile.readData("data", instrumentXML ); + nxFile.closeGroup(); + nxFile.closeGroup(); + + progInitial.report("Loading instrument"); + + Geometry::InstrumentDefinitionParser parser; + std::string instrumentName = "McStas"; + parser.initialize(filename, instrumentName, instrumentXML); + std::string instrumentNameMangled = parser.getMangledName(); + + // Check whether the instrument is already in the InstrumentDataService + if ( InstrumentDataService::Instance().doesExist(instrumentNameMangled) ) + { + // If it does, just use the one from the one stored there + instrument = InstrumentDataService::Instance().retrieve(instrumentNameMangled); + } + else + { + // Really create the instrument + instrument = parser.parseXML(NULL); + // Add to data service for later retrieval + InstrumentDataService::Instance().add(instrumentNameMangled, instrument); + } + } + catch(...) + { + // Loader should not stop if there is no IDF.xml + g_log.warning() <<"\nCould not find the instrument description in the Nexus file:" << filename << " Ignore evntdata from data file" << std::endl; + return; + } + // Finished reading Instrument. Then open new data folder again + nxFile.openGroup("data", "NXdetector"); + + // create and prepare an event workspace ready to receive the mcstas events + progInitial.report("Set up EventWorkspace"); + EventWorkspace_sptr eventWS(new EventWorkspace()); + // initialize, where create up front number of eventlists = number of detectors + eventWS->initialize(instrument->getNumberDetectors(),1,1); + // Set the units + eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); + eventWS->setYUnit("Counts"); + // set the instrument + eventWS->setInstrument(instrument); + // assign detector ID to eventlists + + std::vector detIDs = instrument->getDetectorIDs(); - for (size_t i = 0; i < instrument->getNumberDetectors(); i++) - { - eventWS->getEventList(i).addDetectorID(detIDs[i]); - // spectrum number are treated as equal to detector IDs for McStas data - eventWS->getEventList(i).setSpectrumNo(detIDs[i]); - } - // the one is here for the moment for backward compatibility - eventWS->rebuildSpectraMapping(true); + for (size_t i = 0; i < instrument->getNumberDetectors(); i++) + { + eventWS->getEventList(i).addDetectorID(detIDs[i]); + // spectrum number are treated as equal to detector IDs for McStas data + eventWS->getEventList(i).setSpectrumNo(detIDs[i]); + } + // the one is here for the moment for backward compatibility + eventWS->rebuildSpectraMapping(true); - bool isAnyNeutrons=false; - // to store shortest and longest recorded TOF - double shortestTOF(0.0); - double longestTOF(0.0); - - for(auto eit = eventEntries.begin(); eit != eventEntries.end(); ++eit) - { - std::string dataName = eit->first; - std::string dataType = eit->second; - - // open second level entry - nxFile.openGroup(dataName, dataType); - std::vector data; - nxFile.openData("events"); - nxFile.getData(data); - nxFile.closeData(); - nxFile.closeGroup(); - - // Need to take into account that the nexus readData method reads a multi-column data entry - // into a vector - // The number of data column for each neutron is here hardcoded to (p, x, y, n, id, t) - // Thus we have - // column 0 : p neutron wight - // column 1 : x x coordinate - // column 2 : y y coordinate - // column 3 : n accumulated number of neutrons + bool isAnyNeutrons=false; + // to store shortest and longest recorded TOF + double shortestTOF(0.0); + double longestTOF(0.0); + + const size_t numEventEntries = eventEntries.size(); + Progress progEntries(this, progressFractionInitial, 1.0, numEventEntries*2); + for(auto eit = eventEntries.begin(); eit != eventEntries.end(); ++eit) + { + std::string dataName = eit->first; + std::string dataType = eit->second; + + // open second level entry + nxFile.openGroup(dataName, dataType); + std::vector data; + nxFile.openData("events"); + progEntries.report("read event data from nexus"); + nxFile.getData(data); + nxFile.closeData(); + nxFile.closeGroup(); + + // Need to take into account that the nexus readData method reads a multi-column data entry + // into a vector + // The number of data column for each neutron is here hardcoded to (p, x, y, n, id, t) + // Thus we have + // column 0 : p neutron wight + // column 1 : x x coordinate + // column 2 : y y coordinate + // column 3 : n accumulated number of neutrons // column 4 : id pixel id - // column 5 : t time - - size_t numberOfDataColumn = 6; - // The number of neutrons - size_t nNeutrons = data.size() / numberOfDataColumn; - if (isAnyNeutrons==false && nNeutrons>0) isAnyNeutrons=true; - - // populate workspace with McStas events - const detid2index_map detIDtoWSindex_map = eventWS->getDetectorIDToWorkspaceIndexMap(true); - // This one does not compile on Mac - //detid2index_map* detIDtoWSindex_map = eventWS->getDetectorIDToWorkspaceIndexMap(true); - - for (size_t in = 0; in < nNeutrons; in++) - { - const int detectorID = static_cast(data[4+numberOfDataColumn*in]); - const double detector_time = data[5+numberOfDataColumn*in] * 1.0e6; // convert to microseconds - if ( in == 0 ) - { - shortestTOF = detector_time; - longestTOF = detector_time; - } - else - { - if ( detector_time < shortestTOF ) shortestTOF = detector_time; - if ( detector_time > longestTOF ) longestTOF = detector_time; - } - - // This one does not compile on Mac - //size_t workspaceIndex = (*detIDtoWSindex_map)[detectorID]; - const size_t workspaceIndex = detIDtoWSindex_map.find(detectorID)->second; + // column 5 : t time + + size_t numberOfDataColumn = 6; + // The number of neutrons + size_t nNeutrons = data.size() / numberOfDataColumn; + if (isAnyNeutrons==false && nNeutrons>0) isAnyNeutrons=true; + + // populate workspace with McStas events + const detid2index_map detIDtoWSindex_map = eventWS->getDetectorIDToWorkspaceIndexMap(true); + + progEntries.report("read event data into workspace"); + for (size_t in = 0; in < nNeutrons; in++) + { + const int detectorID = static_cast(data[4+numberOfDataColumn*in]); + const double detector_time = data[5+numberOfDataColumn*in] * 1.0e6; // convert to microseconds + if ( in == 0 ) + { + shortestTOF = detector_time; + longestTOF = detector_time; + } + else + { + if ( detector_time < shortestTOF ) shortestTOF = detector_time; + if ( detector_time > longestTOF ) longestTOF = detector_time; + } + + // This one does not compile on Mac + //size_t workspaceIndex = (*detIDtoWSindex_map)[detectorID]; + const size_t workspaceIndex = detIDtoWSindex_map.find(detectorID)->second; - int64_t pulse_time = 0; - //eventWS->getEventList(workspaceIndex) += TofEvent(detector_time,pulse_time); - //eventWS->getEventList(workspaceIndex) += TofEvent(detector_time); - eventWS->getEventList(workspaceIndex) += WeightedEvent(detector_time, pulse_time, data[numberOfDataColumn*in], 1.0); - } - } - - - // Create a default TOF-vector for histogramming, for now just 2 bins - // 2 bins is the standard. However for McStas simulation data it may make sense to - // increase this number for better initial visual effect - Kernel::cow_ptr axis; - MantidVec& xRef = axis.access(); - xRef.resize(2,0.0); - //if ( nNeutrons > 0) - if(isAnyNeutrons) - { - xRef[0] = shortestTOF - 1; //Just to make sure the bins hold it all - xRef[1] = longestTOF + 1; - } - // Set the binning axis - eventWS->setAllX(axis); + int64_t pulse_time = 0; + //eventWS->getEventList(workspaceIndex) += TofEvent(detector_time,pulse_time); + //eventWS->getEventList(workspaceIndex) += TofEvent(detector_time); + eventWS->getEventList(workspaceIndex) += WeightedEvent(detector_time, pulse_time, data[numberOfDataColumn*in], 1.0); + } + } + + + // Create a default TOF-vector for histogramming, for now just 2 bins + // 2 bins is the standard. However for McStas simulation data it may make sense to + // increase this number for better initial visual effect + Kernel::cow_ptr axis; + MantidVec& xRef = axis.access(); + xRef.resize(2,0.0); + //if ( nNeutrons > 0) + if(isAnyNeutrons) + { + xRef[0] = shortestTOF - 1; //Just to make sure the bins hold it all + xRef[1] = longestTOF + 1; + } + // Set the binning axis + eventWS->setAllX(axis); // ensure that specified name is given to workspace (eventWS) when added to outputGroup std::string nameOfGroupWS = getProperty("OutputWorkspace"); @@ -385,135 +393,135 @@ namespace DataHandling declareProperty(new WorkspaceProperty (extraProperty, nameUserSee, Direction::Output)); setProperty(extraProperty, boost::static_pointer_cast(eventWS)); m_countNumWorkspaceAdded++; // need to increment to ensure extraProperty are unique - - outputGroup->addWorkspace(eventWS); - } + + outputGroup->addWorkspace(eventWS); + } - /** - * Return the confidence with with this algorithm can load the file + /** + * Return the confidence with with this algorithm can load the file * @param histogramEntries map of the file entries that have histogram * @param outputGroup pointer to the workspace group * @param nxFile Reads data from inside first first top entry - * @returns An integer specifying the confidence level. 0 indicates it will not be used - */ - void LoadMcStas::readHistogramData(const std::map& histogramEntries, WorkspaceGroup_sptr& outputGroup, ::NeXus::File& nxFile) - { + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + void LoadMcStas::readHistogramData(const std::map& histogramEntries, WorkspaceGroup_sptr& outputGroup, ::NeXus::File& nxFile) + { - std::string nameAttrValueYLABEL; + std::string nameAttrValueYLABEL; - for(auto eit = histogramEntries.begin(); eit != histogramEntries.end(); ++eit) - { - std::string dataName = eit->first; - std::string dataType = eit->second; + for(auto eit = histogramEntries.begin(); eit != histogramEntries.end(); ++eit) + { + std::string dataName = eit->first; + std::string dataType = eit->second; - // open second level entry - nxFile.openGroup(dataName,dataType); + // open second level entry + nxFile.openGroup(dataName,dataType); // grap title to use to e.g. create workspace name std::string nameAttrValueTITLE; nxFile.getAttr("filename", nameAttrValueTITLE); - if ( nxFile.hasAttr("ylabel") ) - { - nxFile.getAttr("ylabel", nameAttrValueYLABEL); - } - - // Find the axis names - auto nxdataEntries = nxFile.getEntries(); - std::string axis1Name,axis2Name; - for(auto nit = nxdataEntries.begin(); nit != nxdataEntries.end(); ++nit) - { - if(nit->second == "NXparameters") continue; - if(nit->first == "ncount") continue; - nxFile.openData(nit->first); - - if(nxFile.hasAttr("axis") ) - { - int axisNo(0); - nxFile.getAttr("axis", axisNo); - if(axisNo == 1) axis1Name = nit->first; - else if(axisNo==2) axis2Name = nit->first; - else throw std::invalid_argument("Unknown axis number"); - } - nxFile.closeData(); - } - - - std::vector axis1Values,axis2Values; - nxFile.readData(axis1Name,axis1Values); - if (axis2Name.length()==0) - { - axis2Name=nameAttrValueYLABEL; - axis2Values.push_back(0.0); - } - else - { - nxFile.readData(axis2Name,axis2Values); - } - - const size_t axis1Length = axis1Values.size(); - const size_t axis2Length = axis2Values.size(); - g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length << std::endl; + if ( nxFile.hasAttr("ylabel") ) + { + nxFile.getAttr("ylabel", nameAttrValueYLABEL); + } + + // Find the axis names + auto nxdataEntries = nxFile.getEntries(); + std::string axis1Name,axis2Name; + for(auto nit = nxdataEntries.begin(); nit != nxdataEntries.end(); ++nit) + { + if(nit->second == "NXparameters") continue; + if(nit->first == "ncount") continue; + nxFile.openData(nit->first); + + if(nxFile.hasAttr("axis") ) + { + int axisNo(0); + nxFile.getAttr("axis", axisNo); + if(axisNo == 1) axis1Name = nit->first; + else if(axisNo==2) axis2Name = nit->first; + else throw std::invalid_argument("Unknown axis number"); + } + nxFile.closeData(); + } + + + std::vector axis1Values,axis2Values; + nxFile.readData(axis1Name,axis1Values); + if (axis2Name.length()==0) + { + axis2Name=nameAttrValueYLABEL; + axis2Values.push_back(0.0); + } + else + { + nxFile.readData(axis2Name,axis2Values); + } + + const size_t axis1Length = axis1Values.size(); + const size_t axis2Length = axis2Values.size(); + g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length << std::endl; - // Require "data" field - std::vector data; - nxFile.readData("data", data); + // Require "data" field + std::vector data; + nxFile.readData("data", data); - // Optional errors field - std::vector errors; - try - { - nxFile.readData("errors", errors); - } - catch(::NeXus::Exception&) - { - g_log.information() << "Field " << dataName << " contains no error information." << std::endl; - } - - // close second level entry - nxFile.closeGroup(); - - MatrixWorkspace_sptr ws = - WorkspaceFactory::Instance().create("Workspace2D", axis2Length, axis1Length, axis1Length); - Axis *axis1 = ws->getAxis(0); - axis1->title() = axis1Name; - // Set caption - boost::shared_ptr lblUnit(new Units::Label); - lblUnit->setLabel(axis1Name,""); - axis1->unit() = lblUnit; + // Optional errors field + std::vector errors; + try + { + nxFile.readData("errors", errors); + } + catch(::NeXus::Exception&) + { + g_log.information() << "Field " << dataName << " contains no error information." << std::endl; + } + + // close second level entry + nxFile.closeGroup(); + + MatrixWorkspace_sptr ws = + WorkspaceFactory::Instance().create("Workspace2D", axis2Length, axis1Length, axis1Length); + Axis *axis1 = ws->getAxis(0); + axis1->title() = axis1Name; + // Set caption + boost::shared_ptr lblUnit(new Units::Label); + lblUnit->setLabel(axis1Name,""); + axis1->unit() = lblUnit; - - Axis *axis2 = new NumericAxis(axis2Length); - axis2->title() = axis2Name; - // Set caption - lblUnit = boost::shared_ptr(new Units::Label); - lblUnit->setLabel(axis2Name,""); - axis2->unit() = lblUnit; + + Axis *axis2 = new NumericAxis(axis2Length); + axis2->title() = axis2Name; + // Set caption + lblUnit = boost::shared_ptr(new Units::Label); + lblUnit->setLabel(axis2Name,""); + axis2->unit() = lblUnit; - ws->setYUnit(axis2Name); - ws->replaceAxis(1, axis2); + ws->setYUnit(axis2Name); + ws->replaceAxis(1, axis2); - for(size_t wsIndex=0; wsIndex < axis2Length; ++wsIndex) - { - auto &dataY = ws->dataY(wsIndex); - auto &dataE = ws->dataE(wsIndex); - auto &dataX = ws->dataX(wsIndex); - - for(size_t j=0; j < axis1Length; ++j) - { - // Data is stored in column-major order so we are translating to - // row major for Mantid - const size_t fileDataIndex = j*axis2Length + wsIndex; - - dataY[j] = data[fileDataIndex]; - dataX[j] = axis1Values[j]; - if(!errors.empty()) dataE[j] = errors[fileDataIndex]; - } - axis2->setValue(wsIndex, axis2Values[wsIndex]); - } - + for(size_t wsIndex=0; wsIndex < axis2Length; ++wsIndex) + { + auto &dataY = ws->dataY(wsIndex); + auto &dataE = ws->dataE(wsIndex); + auto &dataX = ws->dataX(wsIndex); + + for(size_t j=0; j < axis1Length; ++j) + { + // Data is stored in column-major order so we are translating to + // row major for Mantid + const size_t fileDataIndex = j*axis2Length + wsIndex; + + dataY[j] = data[fileDataIndex]; + dataX[j] = axis1Values[j]; + if(!errors.empty()) dataE[j] = errors[fileDataIndex]; + } + axis2->setValue(wsIndex, axis2Values[wsIndex]); + } + // set the workspace title ws->setTitle(nameAttrValueTITLE); @@ -528,13 +536,13 @@ namespace DataHandling setProperty(extraProperty, boost::static_pointer_cast(ws)); m_countNumWorkspaceAdded++; // need to increment to ensure extraProperty are unique - // Make Mantid store the workspace in the group - outputGroup->addWorkspace(ws); - - } - nxFile.closeGroup(); + // Make Mantid store the workspace in the group + outputGroup->addWorkspace(ws); + + } + nxFile.closeGroup(); - } // finish + } // finish /** @@ -544,30 +552,30 @@ namespace DataHandling */ int LoadMcStas::confidence(Kernel::NexusDescriptor & descriptor) const { - using namespace ::NeXus; - // We will look at the first entry and check for a - // simulation class that contains a name attribute with the value=mcstas - int confidence(0); - try - { - ::NeXus::File file = ::NeXus::File(descriptor.filename()); - auto entries = file.getEntries(); - if(!entries.empty()) - { - auto firstIt = entries.begin(); - file.openGroup(firstIt->first,firstIt->second); - file.openGroup("simulation", "NXnote"); - std::string nameAttrValue; + using namespace ::NeXus; + // We will look at the first entry and check for a + // simulation class that contains a name attribute with the value=mcstas + int confidence(0); + try + { + ::NeXus::File file = ::NeXus::File(descriptor.filename()); + auto entries = file.getEntries(); + if(!entries.empty()) + { + auto firstIt = entries.begin(); + file.openGroup(firstIt->first,firstIt->second); + file.openGroup("simulation", "NXnote"); + std::string nameAttrValue; file.readData("name", nameAttrValue); if(boost::iequals(nameAttrValue, "mccode")) confidence = 98; - file.closeGroup(); - file.closeGroup(); - } - } - catch(::NeXus::Exception&) - { - } - return confidence; + file.closeGroup(); + file.closeGroup(); + } + } + catch(::NeXus::Exception&) + { + } + return confidence; } } // namespace DataHandling From 0eb5aef3bbe6f55d2ea726bbcace4e46b0a3b456 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Thu, 6 Mar 2014 15:30:13 +0000 Subject: [PATCH 098/118] Refs #9051. Widgets for the new option --- .../MantidQtCustomInterfaces/MuonAnalysis.ui | 92 +++++++++++++++---- 1 file changed, 73 insertions(+), 19 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.ui index a8b5133891e3..683ff2c2ce1f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.ui @@ -2027,43 +2027,81 @@ p, li { white-space: pre-wrap; } + + + + + Create new window + + + + + Use previous window + + + + - + - Hides the MantidPlot toolbars. Useful on small screens. + Ensures only the graph for the current data file is displayed. - Hide Toolbars: + New plot policy: - - - - + + + + 0 + + + + 6 + + + 0 + + + + + Hide previous plots + + + + + + + + + 0 + + + - - + + + + Hides the MantidPlot toolbars. Useful on small screens. + - + Hide Toolbars: - - - - Ensures only the graph for the current data file is displayed. - + + - Hide Previous Graphs: + - + Qt::Vertical @@ -2566,7 +2604,6 @@ p, li { white-space: pre-wrap; } yAxisAutoscale showErrorBars plotCreation - hideToolbars muonAnalysisHelpPlotting muonAnalysisHelpDataAnalysis valueTable @@ -2578,7 +2615,24 @@ p, li { white-space: pre-wrap; } muonAnalysisHelpResults - + + + newPlotPolicy + currentIndexChanged(int) + newPlotPolicyOptions + setCurrentIndex(int) + + + 265 + 423 + + + 477 + 423 + + + + From 4b41215fadde0aa13829776f675c20a56c320bf5 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Thu, 6 Mar 2014 15:52:22 +0000 Subject: [PATCH 099/118] Refs #9051. Functionality for retrieving selected policy --- .../MantidQtCustomInterfaces/MuonAnalysis.h | 12 +++++++--- .../CustomInterfaces/src/MuonAnalysis.cpp | 23 ++++++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h index eea253f4b172..cd9c92533715 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h @@ -237,15 +237,18 @@ private slots: private: - // Types of entities we are dealing with + /// Types of entities we are dealing with enum ItemType { Pair, Group }; - // Possible plot types users might request + /// Possible plot types users might request enum PlotType { Asymmetry, Counts, Logorithm }; - // Types of periods + /// Types of periods enum PeriodType { First, Second }; + /// Types of new plot policies + enum NewPlotPolicy { NewWindow, PreviousWindow }; + /// Initialize local Python environment void initLocalPython(); @@ -505,6 +508,9 @@ private slots: /// When data loaded set various buttons etc to active void nowDataAvailable(); + /// Return currently selected new plot policy + NewPlotPolicy newPlotPolicy(); + /// handles option tab work MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab* m_optionTab; /// handles fit data work diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp index cd13cc71db8c..b9481823ed56 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp @@ -399,8 +399,9 @@ void MuonAnalysis::plotItem(ItemType itemType, int tableRow, PlotType plotType) setCurrentDataName( wsNameQ ); } - catch(...) + catch(std::exception& e) { + g_log.error(e.what()); QMessageBox::critical( this, "MuonAnalysis - Error", "Unable to plot the item. Check log for details." ); } @@ -3546,6 +3547,26 @@ void MuonAnalysis::nowDataAvailable() m_uiForm.guessAlphaButton->setEnabled(true); } +/** + * @return Currently selected new plot policy + */ +MuonAnalysis::NewPlotPolicy MuonAnalysis::newPlotPolicy() +{ + QMap policyMap; + policyMap["Create new window"] = NewWindow; + policyMap["Use previous window"] = PreviousWindow; + + QString selectedPolicy = m_uiForm.newPlotPolicy->currentText(); + if ( !policyMap.contains(selectedPolicy) ) + { + throw std::runtime_error("Unknown new plot policy selection"); + } + else + { + return policyMap[selectedPolicy]; + } +} + void MuonAnalysis::openDirectoryDialog() { From 8df6af6b2e960ab0e0f72b774b98fd75a41aa44d Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Thu, 6 Mar 2014 15:53:21 +0000 Subject: [PATCH 100/118] Refs #9051. Update plotting code to use the new option --- .../CustomInterfaces/src/MuonAnalysis.cpp | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp index b9481823ed56..b67726ebc4d3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp @@ -2043,28 +2043,58 @@ QStringList MuonAnalysis::getPeriodLabels() const */ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale) { - // Get plotting params - const QMap& params = getPlotStyleParams(wsName); + // List of script lines which acquire a window for plotting. The window is placed to Python + // variable named 'w';' + QStringList acquireWindowScript; + + NewPlotPolicy policy = newPlotPolicy(); + + if ( policy == PreviousWindow ) + { + QStringList& s = acquireWindowScript; // To keep short + + s << "ew = graph('%WSNAME%-1')"; + s << "if '%WSNAME%' != '%PREV%' and ew != None:"; + s << " ew.close()"; + + s << "pw = graph('%PREV%-1')"; + s << "if pw == None:"; + s << " pw = newGraph('%WSNAME%-1', 0)"; + + s << "w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = pw, clearWindow = True)"; + s << "w.setName('%WSNAME%-1')"; + s << "w.setObjectName('%WSNAME%')"; + s << "w.show()"; + s << "w.setFocus()"; + } + else if ( policy == NewWindow ) + { + QStringList& s = acquireWindowScript; // To keep short + + s << "w = graph('%WSNAME%-1')"; + s << "if w == None:"; + s << " w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%)"; + s << " w.setObjectName('%WSNAME%')"; + s << "else:"; + s << " plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = w, clearWindow = True)"; + s << " w.show()"; + s << " w.setFocus()"; + } QString pyS; - // Try to find existing graph window - pyS = "w = graph('%1-1')\n"; + // Add line separators + pyS += acquireWindowScript.join("\n") + "\n"; - // If doesn't exist - plot it - pyS += "if w == None:\n" - " w = plotSpectrum('%1', 0, %2, %3)\n" - " w.setObjectName('%1')\n"; + // Get plotting params + const QMap& params = getPlotStyleParams(wsName); - // If plot does exist already, it should've just been updated automatically, so we just - // need to make sure it is visible - pyS += "else:\n" - " plotSpectrum('%1', 0, %2, %3, window = w, clearWindow = True)\n" - " w.show()\n" - " w.setFocus()\n"; + // Insert real values + pyS.replace("%WSNAME%", wsName); + pyS.replace("%PREV%", m_currentDataName); + pyS.replace("%ERRORS%", params["ShowErrors"]); + pyS.replace("%CONNECT%", params["ConnectType"]); - pyS = pyS.arg(wsName).arg(params["ShowErrors"]).arg(params["ConnectType"]); - // Update titles pyS += "l = w.activeLayer()\n" "l.setCurveTitle(0, '%1')\n" From f3ff6025d95b22231f0a7657b30b00e655ef7774 Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Thu, 6 Mar 2014 15:58:02 +0000 Subject: [PATCH 101/118] Refs #9051. Move plot hiding to more appropriate place And disable it when using previous window --- .../MantidQt/CustomInterfaces/src/MuonAnalysis.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp index b67726ebc4d3..8b62ffbb56de 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp @@ -390,10 +390,6 @@ void MuonAnalysis::plotItem(ItemType itemType, int tableRow, PlotType plotType) QString wsNameQ = QString::fromStdString(wsName); - // Hide all the previous plot windows, if requested by user - if (m_uiForm.hideGraphs->isChecked()) - hideAllPlotWindows(); - // Plot the workspace plotSpectrum( wsNameQ, (plotType == Logorithm) ); @@ -2049,6 +2045,12 @@ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale) NewPlotPolicy policy = newPlotPolicy(); + // Hide all the previous plot windows, if creating a new one + if ( policy == NewWindow && m_uiForm.hideGraphs->isChecked()) + { + hideAllPlotWindows(); + } + if ( policy == PreviousWindow ) { QStringList& s = acquireWindowScript; // To keep short From 35a4a06afaa05b51e40417596d5ba58f953c72ef Mon Sep 17 00:00:00 2001 From: Arturs Bekasovs Date: Thu, 6 Mar 2014 16:04:33 +0000 Subject: [PATCH 102/118] Refs #9051. Move the option retrieval stuff to settings tab code Plus make it's value auto-saveable --- .../MantidQtCustomInterfaces/MuonAnalysis.h | 6 ---- .../MuonAnalysisOptionTab.h | 7 +++++ .../CustomInterfaces/src/MuonAnalysis.cpp | 29 +++---------------- .../src/MuonAnalysisOptionTab.cpp | 23 +++++++++++++++ 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h index cd9c92533715..0a40c4b2b382 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysis.h @@ -246,9 +246,6 @@ private slots: /// Types of periods enum PeriodType { First, Second }; - /// Types of new plot policies - enum NewPlotPolicy { NewWindow, PreviousWindow }; - /// Initialize local Python environment void initLocalPython(); @@ -508,9 +505,6 @@ private slots: /// When data loaded set various buttons etc to active void nowDataAvailable(); - /// Return currently selected new plot policy - NewPlotPolicy newPlotPolicy(); - /// handles option tab work MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab* m_optionTab; /// handles fit data work diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysisOptionTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysisOptionTab.h index 8b91011a04a8..38fc20cb980e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysisOptionTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MuonAnalysisOptionTab.h @@ -48,6 +48,9 @@ class MuonAnalysisOptionTab : public QWidget { Q_OBJECT public: + /// Types of new plot policies + enum NewPlotPolicy { NewWindow, PreviousWindow }; + /// Constructor MuonAnalysisOptionTab(Ui::MuonAnalysis& uiForm, const QString& settingsGroup); @@ -57,6 +60,9 @@ class MuonAnalysisOptionTab : public QWidget /// Get plot style parameters from widgets QMap parsePlotStyleParams() const; + /// Return currently selected new plot policy + NewPlotPolicy newPlotPolicy(); + signals: /// Update the plot because something has changed. void settingsTabUpdatePlot(); @@ -65,6 +71,7 @@ class MuonAnalysisOptionTab : public QWidget void plotStyleChanged(); private: + /// The Muon Analysis UI file. Ui::MuonAnalysis& m_uiForm; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp index 8b62ffbb56de..cfa8440a72a8 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp @@ -2043,15 +2043,15 @@ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale) // variable named 'w';' QStringList acquireWindowScript; - NewPlotPolicy policy = newPlotPolicy(); + MuonAnalysisOptionTab::NewPlotPolicy policy = m_optionTab->newPlotPolicy(); // Hide all the previous plot windows, if creating a new one - if ( policy == NewWindow && m_uiForm.hideGraphs->isChecked()) + if ( policy == MuonAnalysisOptionTab::NewWindow && m_uiForm.hideGraphs->isChecked()) { hideAllPlotWindows(); } - if ( policy == PreviousWindow ) + if ( policy == MuonAnalysisOptionTab::PreviousWindow ) { QStringList& s = acquireWindowScript; // To keep short @@ -2069,7 +2069,7 @@ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale) s << "w.show()"; s << "w.setFocus()"; } - else if ( policy == NewWindow ) + else if ( policy == MuonAnalysisOptionTab::NewWindow ) { QStringList& s = acquireWindowScript; // To keep short @@ -3579,27 +3579,6 @@ void MuonAnalysis::nowDataAvailable() m_uiForm.guessAlphaButton->setEnabled(true); } -/** - * @return Currently selected new plot policy - */ -MuonAnalysis::NewPlotPolicy MuonAnalysis::newPlotPolicy() -{ - QMap policyMap; - policyMap["Create new window"] = NewWindow; - policyMap["Use previous window"] = PreviousWindow; - - QString selectedPolicy = m_uiForm.newPlotPolicy->currentText(); - if ( !policyMap.contains(selectedPolicy) ) - { - throw std::runtime_error("Unknown new plot policy selection"); - } - else - { - return policyMap[selectedPolicy]; - } -} - - void MuonAnalysis::openDirectoryDialog() { MantidQt::API::ManageUserDirectories *ad = new MantidQt::API::ManageUserDirectories(this); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysisOptionTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysisOptionTab.cpp index 3b49b93252d8..1a246928460d 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysisOptionTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysisOptionTab.cpp @@ -53,6 +53,7 @@ void MuonAnalysisOptionTab::initLayout() m_autoSaver.beginGroup("GeneralOptions"); m_autoSaver.registerWidget(m_uiForm.plotCreation, "plotCreation", 0); + m_autoSaver.registerWidget(m_uiForm.newPlotPolicy, "newPlotPolicy", 0); m_autoSaver.registerWidget(m_uiForm.hideToolbars, "toolbars", true); m_autoSaver.registerWidget(m_uiForm.hideGraphs, "hiddenGraphs", true); m_autoSaver.endGroup(); @@ -216,6 +217,28 @@ QMap MuonAnalysisOptionTab::parsePlotStyleParams() const return(params); } +/** + * @return Currently selected new plot policy + */ +MuonAnalysisOptionTab::NewPlotPolicy MuonAnalysisOptionTab::newPlotPolicy() +{ + QMap policyMap; + policyMap["Create new window"] = NewWindow; + policyMap["Use previous window"] = PreviousWindow; + + QString selectedPolicy = m_uiForm.newPlotPolicy->currentText(); + if ( !policyMap.contains(selectedPolicy) ) + { + throw std::runtime_error("Unknown new plot policy selection"); + } + else + { + return policyMap[selectedPolicy]; + } +} + + + } } } From fcb35d8d19a9117cc678942d0c8e0da4fd9aeae2 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Mon, 10 Feb 2014 15:39:15 -0500 Subject: [PATCH 103/118] Re #8487. Use Poco::AutoPtr in place of manual calls to release(). --- .../Instrument/InstrumentDefinitionParser.cpp | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index 1be030b78f6c..fd146f1a8e25 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -225,10 +225,11 @@ namespace Geometry // check if contain . If this then such // types are adjusted after this loop has completed - NodeList* pNL_type_combine_into_one_shape = pTypeElem->getElementsByTagName("combine-components-into-one-shape"); - if ( pNL_type_combine_into_one_shape->length() ) + Poco::AutoPtr pNL_type_combine_into_one_shape = pTypeElem->getElementsByTagName("combine-components-into-one-shape"); + if ( pNL_type_combine_into_one_shape->length() > 0 ) + { continue; - pNL_type_combine_into_one_shape->release(); + } // Each type in the IDF must be uniquely named, hence return error if type // has already been defined @@ -241,7 +242,7 @@ namespace Geometry // identify for now a type to be an assemble by it containing elements // with tag name 'component' - NodeList* pNL_local = pTypeElem->getElementsByTagName("component"); + Poco::AutoPtr pNL_local = pTypeElem->getElementsByTagName("component"); if (pNL_local->length() == 0) { isTypeAssembly[typeName] = false; @@ -259,7 +260,6 @@ namespace Geometry pTypeElem->setAttribute("object_created","no"); } } - pNL_local->release(); } // Deal with adjusting types containing @@ -323,7 +323,7 @@ namespace Geometry // // do analysis for each top level compoment element // - NodeList* pNL_comp = pRootElem->childNodes(); // here get all child nodes + Poco::AutoPtr pNL_comp = pRootElem->childNodes(); // here get all child nodes unsigned long pNL_comp_length = pNL_comp->length(); if (prog) prog->resetNumSteps(pNL_comp_length, 0.0, 1.0); @@ -342,8 +342,8 @@ namespace Geometry // Get all and elements contained in component element // just for the purpose of a IDF syntax check - NodeList* pNL_location = pElem->getElementsByTagName("location"); - NodeList* pNL_locations = pElem->getElementsByTagName("locations"); + Poco::AutoPtr pNL_location = pElem->getElementsByTagName("location"); + Poco::AutoPtr pNL_locations = pElem->getElementsByTagName("locations"); // do a IDF syntax check if (pNL_location->length() == 0 && pNL_locations->length() == 0) { @@ -353,15 +353,13 @@ namespace Geometry std::string("A component element must contain at least one or element") + " even if it is just an empty location element of the form ", filename); } - pNL_location->release(); - pNL_locations->release(); // Loop through all and elements of this component by looping // all the child nodes and then see if any of these nodes are either or // elements. Done this way order these locations are processed is the // order they are listed in the IDF. The latter needed to get detector IDs assigned // as expected - NodeList* pNL_childs = pElem->childNodes(); // here get all child nodes + Poco::AutoPtr pNL_childs = pElem->childNodes(); // here get all child nodes unsigned long pNL_childs_length = pNL_childs->length(); for (unsigned long iLoc = 0; iLoc < pNL_childs_length; iLoc++) { @@ -420,11 +418,9 @@ namespace Geometry + pElem->getAttribute("type") + " (=" + ss2.str() + ").", filename); } idList.reset(); - pNL_childs->release(); } } - pNL_comp->release(); // Don't need this anymore (if it was even used) so empty it out to save memory m_tempPosHolder.clear(); @@ -1647,7 +1643,7 @@ namespace Geometry if ( hasParameterElement_beenSet ) if ( hasParameterElement.end() == std::find(hasParameterElement.begin(),hasParameterElement.end(),pElem) ) return; - NodeList* pNL_comp = pElem->childNodes(); // here get all child nodes + Poco::AutoPtr pNL_comp = pElem->childNodes(); // here get all child nodes unsigned long pNL_comp_length = pNL_comp->length(); for (unsigned long i = 0; i < pNL_comp_length; i++) @@ -1682,18 +1678,18 @@ namespace Geometry std::string extractSingleValueAs = "mean"; // default std::string eq = ""; - NodeList* pNLvalue = pParamElem->getElementsByTagName("value"); + Poco::AutoPtr pNLvalue = pParamElem->getElementsByTagName("value"); size_t numberValueEle = pNLvalue->length(); Element* pValueElem; - NodeList* pNLlogfile = pParamElem->getElementsByTagName("logfile"); + Poco::AutoPtr pNLlogfile = pParamElem->getElementsByTagName("logfile"); size_t numberLogfileEle = pNLlogfile->length(); Element* pLogfileElem; - NodeList* pNLLookUp = pParamElem->getElementsByTagName("lookuptable"); + Poco::AutoPtr pNLLookUp = pParamElem->getElementsByTagName("lookuptable"); size_t numberLookUp = pNLLookUp->length(); - NodeList* pNLFormula = pParamElem->getElementsByTagName("formula"); + Poco::AutoPtr pNLFormula = pParamElem->getElementsByTagName("formula"); size_t numberFormula = pNLFormula->length(); if ( numberValueEle+numberLogfileEle+numberLookUp+numberFormula > 1 ) @@ -1738,9 +1734,6 @@ namespace Geometry if ( pLogfileElem->hasAttribute("extract-single-value-as") ) extractSingleValueAs = pLogfileElem->getAttribute("extract-single-value-as"); } - pNLlogfile->release(); - pNLvalue->release(); - if ( pParamElem->hasAttribute("type") ) type = pParamElem->getAttribute("type"); @@ -1749,13 +1742,12 @@ namespace Geometry // check if element present bool fixed = false; - NodeList* pNLFixed = pParamElem->getElementsByTagName("fixed"); + Poco::AutoPtr pNLFixed = pParamElem->getElementsByTagName("fixed"); size_t numberFixed = pNLFixed->length(); if ( numberFixed >= 1 ) { fixed = true; } - pNLFixed->release(); // some processing @@ -1793,9 +1785,9 @@ namespace Geometry std::vector constraint(2, ""); - NodeList* pNLMin = pParamElem->getElementsByTagName("min"); + Poco::AutoPtr pNLMin = pParamElem->getElementsByTagName("min"); size_t numberMin = pNLMin->length(); - NodeList* pNLMax = pParamElem->getElementsByTagName("max"); + Poco::AutoPtr pNLMax = pParamElem->getElementsByTagName("max"); size_t numberMax = pNLMax->length(); if ( numberMin >= 1) @@ -1808,15 +1800,12 @@ namespace Geometry Element* pMax = static_cast(pNLMax->item(0)); constraint[1] = pMax->getAttribute("val"); } - pNLMin->release(); - pNLMax->release(); - // check if penalty-factor> elements present std::string penaltyFactor; - NodeList* pNL_penaltyFactor = pParamElem->getElementsByTagName("penalty-factor"); + Poco::AutoPtr pNL_penaltyFactor = pParamElem->getElementsByTagName("penalty-factor"); size_t numberPenaltyFactor = pNL_penaltyFactor->length(); if ( numberPenaltyFactor>= 1) @@ -1824,8 +1813,6 @@ namespace Geometry Element* pPenaltyFactor = static_cast(pNL_penaltyFactor->item(0)); penaltyFactor = pPenaltyFactor->getAttribute("val"); } - pNL_penaltyFactor->release(); - // Check if look up table is specified @@ -1864,7 +1851,7 @@ namespace Geometry interpolation->setYUnit(pLookUp->getAttribute("y-unit")); } - NodeList* pNLpoint = pLookUp->getElementsByTagName("point"); + Poco::AutoPtr pNLpoint = pLookUp->getElementsByTagName("point"); unsigned long numberPoint = pNLpoint->length(); for ( unsigned long i = 0; i < numberPoint; i++) @@ -1874,10 +1861,7 @@ namespace Geometry double y = atof( pPoint->getAttribute("y").c_str() ); interpolation->addPoint(x,y); } - pNLpoint->release(); } - pNLLookUp->release(); - // Check if formula is specified @@ -1904,8 +1888,6 @@ namespace Geometry if ( pFormula->hasAttribute("result-unit") ) resultUnit = pFormula->getAttribute("result-unit"); } - pNLFormula->release(); - auto cacheKey = std::make_pair(paramName, comp); auto cacheValue = boost::shared_ptr(new XMLlogfile(logfileID, value, interpolation, formula, formulaUnit, resultUnit, @@ -1918,7 +1900,6 @@ namespace Geometry } } // end of if statement } - pNL_comp->release(); } @@ -2242,7 +2223,7 @@ namespace Geometry } // Get pointer to root element and add this element to pElem Element* pCuboid = pDoc->documentElement(); - Node* fisse = (pElem->ownerDocument())->importNode(pCuboid, true); + Poco::AutoPtr fisse = (pElem->ownerDocument())->importNode(pCuboid, true); pElem->appendChild(fisse); pDoc->release(); From b3d6ff84c1dc0a89c5d7c645198d59b247e93a7e Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 11:44:22 -0500 Subject: [PATCH 104/118] Re #8487. Remove trial print added in #9118 & left in by mistake. --- Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h index 0814d7590482..c64146dd8e23 100644 --- a/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/IMDDimensionFactoryTest.h @@ -100,10 +100,6 @@ class IMDDimensionFactoryTest: public CxxTest::TestSuite TS_ASSERT_THROWS( createDimension(""), std::invalid_argument ); TS_ASSERT_THROWS( createDimension("garbage"), std::invalid_argument ); - std::string xmlString = constructNonReciprocalDimensionXMLString(); - xmlString.erase(96,30); - std::cout << xmlString << std::endl; - std::string missingID = constructNonReciprocalDimensionXMLString().erase(10,8); TS_ASSERT_THROWS( createDimension(missingID), std::invalid_argument ); std::string missingName = constructNonReciprocalDimensionXMLString().erase(19,19); From 3298f7808bece5b2f18c9d5f15378ea0ed16a9f8 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 11:44:53 -0500 Subject: [PATCH 105/118] Re #8487. Don't leak memory due to Poco calls. --- .../Geometry/src/MDGeometry/MDGeometryXMLParser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp index 22b5ebac17e0..d3759932b97b 100644 --- a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLParser.cpp @@ -9,8 +9,9 @@ #include #include #include +#include -#include +#include namespace Mantid { @@ -58,7 +59,7 @@ namespace Mantid typedef std::vector::iterator Iterator; Poco::XML::DOMParser pParser; - Poco::XML::Document* pDoc = pParser.parseString(m_xmlToProcess); + Poco::AutoPtr pDoc = pParser.parseString(m_xmlToProcess); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Apply root node checking if supplied. Poco::XML::Element* geometryXMLElement = NULL; @@ -79,7 +80,7 @@ namespace Mantid } - Poco::XML::NodeList* dimensionsXML = geometryXMLElement-> getElementsByTagName(MDGeometryXMLDefinitions::workspaceDimensionElementName()); + Poco::AutoPtr dimensionsXML = geometryXMLElement-> getElementsByTagName(MDGeometryXMLDefinitions::workspaceDimensionElementName()); size_t nDimensions = dimensionsXML->length(); VecIMDDimension_sptr vecAllDims(nDimensions); From 668b03e2cfcd31426b368ee98a61c78e265c6189 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:21:00 -0500 Subject: [PATCH 106/118] Re #8487. Ensure Poco XML call doesn't leak memory. --- .../Framework/Geometry/src/MDGeometry/MDGeometryXMLBuilder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLBuilder.cpp b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLBuilder.cpp index 304497617937..5921bf8042fb 100644 --- a/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLBuilder.cpp +++ b/Code/Mantid/Framework/Geometry/src/MDGeometry/MDGeometryXMLBuilder.cpp @@ -222,7 +222,8 @@ const std::string& MDGeometryBuilderXML::create() const } //Pass dimensions to dimension set. - dimensionSetElement->appendChild(pDoc->createTextNode("%s")); + AutoPtr percents = pDoc->createTextNode("%s"); + dimensionSetElement->appendChild(percents); //x-dimension mapping. AutoPtr xDimensionElement = pDoc->createElement("XDimension"); From ce7af193503a0fe50227e16c896a1f6ab78003b2 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:21:37 -0500 Subject: [PATCH 107/118] Re #8487. Eliminate Poco-related leaks in test. --- .../Geometry/test/MDGeometryXMLBuilderTest.h | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/MDGeometryXMLBuilderTest.h b/Code/Mantid/Framework/Geometry/test/MDGeometryXMLBuilderTest.h index 8c018a91eb2d..7b40c2e0cb98 100644 --- a/Code/Mantid/Framework/Geometry/test/MDGeometryXMLBuilderTest.h +++ b/Code/Mantid/Framework/Geometry/test/MDGeometryXMLBuilderTest.h @@ -20,6 +20,7 @@ #include #include #include +#include using namespace Mantid; using namespace Mantid::Geometry; @@ -195,18 +196,18 @@ void testWithOrinaryDimensionOnly() Poco::XML::DOMParser pParser; std::string xmlToParse = builder.create(); //Serialize the geometry. - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); + Poco::AutoPtr pDoc = pParser.parseString(xmlToParse); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Check that the number of dimensions provided is correct. - TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 1, pRootElem->getElementsByTagName("Dimension")->length()); + Poco::AutoPtr dimension = pRootElem->getElementsByTagName("Dimension"); + TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 1, dimension->length()); //Check that mapping nodes give correct mappings. - Poco::XML::Element* dimensionSetElement = pRootElem; - TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", dimensionSetElement->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", dimensionSetElement->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", dimensionSetElement->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", dimensionSetElement->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", pRootElem->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", pRootElem->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", pRootElem->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", pRootElem->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); } void testManyOrinaryDimensions() @@ -250,18 +251,18 @@ void testWithXDimensionOnly() Poco::XML::DOMParser pParser; std::string xmlToParse = builder.create(); //Serialize the geometry. - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); + Poco::AutoPtr pDoc = pParser.parseString(xmlToParse); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Check that the number of dimensions provided is correct. - TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 1, pRootElem->getElementsByTagName("Dimension")->length()); + Poco::AutoPtr dimension = pRootElem->getElementsByTagName("Dimension"); + TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 1, dimension->length()); //Check that mapping nodes give correct mappings. - Poco::XML::Element* dimensionSetElement = pRootElem; - TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", dimensionSetElement->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", dimensionSetElement->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", dimensionSetElement->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", dimensionSetElement->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", pRootElem->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "", pRootElem->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", pRootElem->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", pRootElem->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); } void testWithXYDimensionOnly() @@ -282,18 +283,18 @@ void testWithXYDimensionOnly() Poco::XML::DOMParser pParser; std::string xmlToParse = builder.create(); //Serialize the geometry. - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); + Poco::AutoPtr pDoc = pParser.parseString(xmlToParse); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Check that the number of dimensions provided is correct. - TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 2, pRootElem->getElementsByTagName("Dimension")->length()); + Poco::AutoPtr dimension = pRootElem->getElementsByTagName("Dimension"); + TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 2, dimension->length()); //Check that mapping nodes give correct mappings. - Poco::XML::Element* dimensionSetElement = pRootElem; - TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", dimensionSetElement->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "b", dimensionSetElement->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", dimensionSetElement->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", dimensionSetElement->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", pRootElem->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "b", pRootElem->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "", pRootElem->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", pRootElem->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); } void testWithXYZDimensionOnly() @@ -319,18 +320,18 @@ void testWithXYZDimensionOnly() Poco::XML::DOMParser pParser; std::string xmlToParse = builder.create(); //Serialize the geometry. - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); + Poco::AutoPtr pDoc = pParser.parseString(xmlToParse); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Check that the number of dimensions provided is correct. - TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 3, pRootElem->getElementsByTagName("Dimension")->length()); + Poco::AutoPtr dimension = pRootElem->getElementsByTagName("Dimension"); + TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 3, dimension->length()); //Check that mapping nodes give correct mappings. - Poco::XML::Element* dimensionSetElement = pRootElem; - TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", dimensionSetElement->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "b", dimensionSetElement->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "c", dimensionSetElement->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", dimensionSetElement->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", pRootElem->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionY mapping", "b", pRootElem->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionZ mapping", "c", pRootElem->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("Should have no DimensionT mapping", "", pRootElem->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); } void testFullCreate() @@ -362,24 +363,28 @@ void testFullCreate() Poco::XML::DOMParser pParser; std::string xmlToParse = builder.create(); //Serialize the geometry. - Poco::XML::Document* pDoc = pParser.parseString(xmlToParse); + Poco::AutoPtr pDoc = pParser.parseString(xmlToParse); Poco::XML::Element* pRootElem = pDoc->documentElement(); //Check that the number of dimensions provided is correct. - TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 4, pRootElem->getElementsByTagName("Dimension")->length()); + Poco::AutoPtr dimension = pRootElem->getElementsByTagName("Dimension"); + TSM_ASSERT_EQUALS("Wrong number of dimensions in geometry xml", 4, dimension->length()); //Check that mapping nodes have been provided. - TSM_ASSERT_EQUALS("No DimensionX in geometry xml", 1, pRootElem->getElementsByTagName("XDimension")->length()); - TSM_ASSERT_EQUALS("No DimensionY in geometry xml", 1, pRootElem->getElementsByTagName("YDimension")->length()); - TSM_ASSERT_EQUALS("No DimensionZ in geometry xml", 1, pRootElem->getElementsByTagName("ZDimension")->length()); - TSM_ASSERT_EQUALS("No DimensionT in geometry xml", 1, pRootElem->getElementsByTagName("TDimension")->length()); + Poco::AutoPtr xdimension = pRootElem->getElementsByTagName("XDimension"); + TSM_ASSERT_EQUALS("No DimensionX in geometry xml", 1, xdimension->length()); + Poco::AutoPtr ydimension = pRootElem->getElementsByTagName("YDimension"); + TSM_ASSERT_EQUALS("No DimensionY in geometry xml", 1, ydimension->length()); + Poco::AutoPtr zdimension = pRootElem->getElementsByTagName("ZDimension"); + TSM_ASSERT_EQUALS("No DimensionZ in geometry xml", 1, zdimension->length()); + Poco::AutoPtr tdimension = pRootElem->getElementsByTagName("TDimension"); + TSM_ASSERT_EQUALS("No DimensionT in geometry xml", 1, tdimension->length()); //Check that mapping nodes give correct mappings. - Poco::XML::Element* dimensionSetElement = pRootElem; - TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", dimensionSetElement->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("No DimensionY mapping is incorrect", "b", dimensionSetElement->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("No DimensionZ mapping is incorrect", "c", dimensionSetElement->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); - TSM_ASSERT_EQUALS("No DimensionT mapping is incorrect", "d", dimensionSetElement->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionX mapping is incorrect", "a", pRootElem->getChildElement("XDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionY mapping is incorrect", "b", pRootElem->getChildElement("YDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionZ mapping is incorrect", "c", pRootElem->getChildElement("ZDimension")->getChildElement("RefDimensionId")->innerText()); + TSM_ASSERT_EQUALS("No DimensionT mapping is incorrect", "d", pRootElem->getChildElement("TDimension")->getChildElement("RefDimensionId")->innerText()); } }; From a0f15138715ba280239583942ee33a38b402e2e0 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:40:32 -0500 Subject: [PATCH 108/118] Re #8487. Replace manual calls to release with AutoPtr use. --- .../Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp index 414b0355e1ae..7d0b0298a97e 100644 --- a/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -68,7 +68,7 @@ boost::shared_ptr ShapeFactory::createShape(std::string shapeXML, bool a // Set up the DOM parser and parse xml string DOMParser pParser; - Document* pDoc; + Poco::AutoPtr pDoc; try { pDoc = pParser.parseString(shapeXML); @@ -84,7 +84,6 @@ boost::shared_ptr ShapeFactory::createShape(std::string shapeXML, bool a //convert into a Geometry object boost::shared_ptr retVal = createShape(pRootElem); - pDoc->release(); return retVal; } @@ -142,7 +141,7 @@ boost::shared_ptr ShapeFactory::createShape(Poco::XML::Element* pElem) // loop over all the sub-elements of pElem - NodeList* pNL = pElem->childNodes(); // get all child nodes + Poco::AutoPtr pNL = pElem->childNodes(); // get all child nodes unsigned long pNL_length = pNL->length(); int numPrimitives = 0; // used for counting number of primitives in this 'type' XML element std::map primitives; // stores the primitives that will be used to build final shape @@ -249,8 +248,6 @@ boost::shared_ptr ShapeFactory::createShape(Poco::XML::Element* pElem) } } } - - pNL->release(); if ( defaultAlgebra == false ) { From bfc2d4d0066d1ffc6c71dc85aac95ba0edf83f1a Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:42:09 -0500 Subject: [PATCH 109/118] Re #8487. Replace tabs with spaces. No code changes. --- .../Geometry/src/Objects/ShapeFactory.cpp | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp index 7d0b0298a97e..95a287f89531 100644 --- a/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Code/Mantid/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -62,28 +62,28 @@ ShapeFactory::ShapeFactory() */ boost::shared_ptr ShapeFactory::createShape(std::string shapeXML, bool addTypeTag) { - //wrap in a type tag + //wrap in a type tag if (addTypeTag) shapeXML = " " + shapeXML + " "; - // Set up the DOM parser and parse xml string - DOMParser pParser; - Poco::AutoPtr pDoc; - try - { - pDoc = pParser.parseString(shapeXML); - } - catch(...) - { - g_log.warning("Unable to parse XML string " + shapeXML + " . Empty geometry Object is returned."); + // Set up the DOM parser and parse xml string + DOMParser pParser; + Poco::AutoPtr pDoc; + try + { + pDoc = pParser.parseString(shapeXML); + } + catch(...) + { + g_log.warning("Unable to parse XML string " + shapeXML + " . Empty geometry Object is returned."); boost::shared_ptr retVal = boost::shared_ptr(new Object); return retVal; - } - // Get pointer to root element - Element* pRootElem = pDoc->documentElement(); + } + // Get pointer to root element + Element* pRootElem = pDoc->documentElement(); - //convert into a Geometry object - boost::shared_ptr retVal = createShape(pRootElem); + //convert into a Geometry object + boost::shared_ptr retVal = createShape(pRootElem); return retVal; } @@ -237,14 +237,14 @@ boost::shared_ptr ShapeFactory::createShape(Poco::XML::Element* pElem) g_log.warning(primitiveName + " not a recognised geometric shape. This shape is ignored."); } } - catch (std::invalid_argument& e) - { - g_log.warning() << e.what() << " <" << primitiveName << "> shape is ignored."; - } - catch (...) - { - g_log.warning() << " Problem with parsing XML string for <" << primitiveName << ">. This shape is ignored."; - } + catch (std::invalid_argument& e) + { + g_log.warning() << e.what() << " <" << primitiveName << "> shape is ignored."; + } + catch (...) + { + g_log.warning() << " Problem with parsing XML string for <" << primitiveName << ">. This shape is ignored."; + } } } } From ec7417f0e3e2d9e1a0adac60a3a601d57aa89608 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:45:05 -0500 Subject: [PATCH 110/118] Re #8487. Replace manual call to release with AutoPtr. --- Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h b/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h index c855caeb95a1..4869c9c546d8 100644 --- a/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h @@ -10,6 +10,7 @@ #include #include #include +#include using Poco::XML::DOMParser; using Poco::XML::Document; @@ -566,9 +567,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite // Set up the DOM parser and parse xml string DOMParser pParser; - Document* pDoc; - - pDoc = pParser.parseString(shapeXML); + Poco::AutoPtr pDoc = pParser.parseString(shapeXML); // Get pointer to root element Element* pRootElem = pDoc->documentElement(); @@ -576,7 +575,6 @@ class ShapeFactoryTest : public CxxTest::TestSuite //convert into a Geometry object ShapeFactory sFactory; boost::shared_ptr shape_sptr = sFactory.createShape(pRootElem); - pDoc->release(); return shape_sptr; } From 07e28e51211fc20ac99c3df66ec2c6ab4bfa1d1c Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 12:50:08 -0500 Subject: [PATCH 111/118] Re #8487. Replace tabs with spaces. No code changed. --- .../Geometry/test/ShapeFactoryTest.h | 398 +++++++++--------- 1 file changed, 199 insertions(+), 199 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h b/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h index 4869c9c546d8..300957ea385d 100644 --- a/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h +++ b/Code/Mantid/Framework/Geometry/test/ShapeFactoryTest.h @@ -24,24 +24,24 @@ class ShapeFactoryTest : public CxxTest::TestSuite { public: - void testCuboid() - { - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " "; - xmlShape += " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); + void testCuboid() + { + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " "; + xmlShape += " "; + + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,0.00001)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,0.001)) ); TS_ASSERT( shape_sptr->isValid(V3D(-0.004,0.0,0.00001)) ); TS_ASSERT( !shape_sptr->isValid(V3D(-0.006,0.0,0.00001)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.09, 0.00001)) ); - } + } void testAlternateCuboid() { @@ -54,7 +54,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite xmlShape += ""; // Note non-default axis. xmlShape += ""; xmlShape += ""; - + auto cuboid = getObject(xmlShape); TS_ASSERT( cuboid->isValid(V3D(1.20, 1.10, 0.95)) ); @@ -86,7 +86,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite xmlShape += ""; xmlShape += ""; xmlShape += ""; - + auto cuboid = getObject(xmlShape); TS_ASSERT( cuboid->isValid(V3D( 1.05, 1.10, 1.20)) ); @@ -118,7 +118,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite xmlShape += ""; xmlShape += ""; xmlShape += ""; - + auto cuboid = getObject(xmlShape); TS_ASSERT( cuboid->isValid(V3D( 0.05, 0.10, 0.20)) ); @@ -144,25 +144,25 @@ class ShapeFactoryTest : public CxxTest::TestSuite { //Create a cuboid. std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " "; - xmlShape += " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " "; + xmlShape += " "; std::string expectedXML = " " + xmlShape + " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); + + boost::shared_ptr shape_sptr = getObject(xmlShape); TSM_ASSERT("Empty shape xml given.", !shape_sptr->getShapeXML().empty()); TSM_ASSERT_EQUALS("Shape xml not relayed through to shape object.", expectedXML, shape_sptr->getShapeXML()); } - void testHexahedron() - { - std::string xmlShape = " "; + void testHexahedron() + { + std::string xmlShape = " "; xmlShape += " " ; xmlShape += " " ; xmlShape += " " ; @@ -171,21 +171,21 @@ class ShapeFactoryTest : public CxxTest::TestSuite xmlShape += " " ; xmlShape += " " ; xmlShape += " " ; - xmlShape += " "; - xmlShape += " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); + xmlShape += " "; + xmlShape += " "; + + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,0.0)) ); TS_ASSERT( !shape_sptr->isValid(V3D(1.1,0.0,0.0)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.9,0.9,0.0)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.49,0.49,1.99)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.49,0.81, 1.99)) ); - } - - void testHexahedron2() - { - std::string xmlShape = " "; + } + + void testHexahedron2() + { + std::string xmlShape = " "; xmlShape += " " ; xmlShape += " " ; xmlShape += " " ; @@ -194,10 +194,10 @@ class ShapeFactoryTest : public CxxTest::TestSuite xmlShape += " " ; xmlShape += " " ; xmlShape += " " ; - xmlShape += " "; - xmlShape += " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); + xmlShape += " "; + xmlShape += " "; + + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0001,0.0,0.0)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0055,0.0,0.0)) ); @@ -205,7 +205,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.-0.003,-0.036)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,-0.003, -0.038)) ); } - + void testTaperedGuideDefaults() { std::string xmlShape = ""; @@ -239,7 +239,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT(!shape_sptr->isValid(V3D(-1.6, 1.6, 1.0)) ); TS_ASSERT(!shape_sptr->isValid(V3D(-1.6,-1.6, 1.0)) ); } - + void testTaperedGuideDifferentAxisAndCentre() { std::string xmlShape = ""; @@ -276,38 +276,38 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( !shape_sptr->isValid(V3D( 1.0, 1.6, 2.6)) ); } - void testSphere() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testSphere() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,8.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(47.1,2.1,8.1)) ); TS_ASSERT( shape_sptr->isValid(V3D(5.1,2.1,8.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(-0.006,0.0,0.00001)) ); TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,9.1)) ); - } - - void testTwoSpheres() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; + } + + void testTwoSpheres() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; xmlShape += " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,8.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(47.1,2.1,8.1)) ); @@ -316,21 +316,21 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,9.1)) ); TS_ASSERT( shape_sptr->isValid(V3D(-0.8,2.1,9.1)) ); TS_ASSERT( shape_sptr->isValid(V3D(7.1,2.1,9.1)) ); - } - - void testTwoSpheresNoAlgebraString() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; + } + + void testTwoSpheresNoAlgebraString() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; xmlShape += " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,8.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(47.1,2.1,8.1)) ); @@ -339,7 +339,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( shape_sptr->isValid(V3D(4.1,2.1,9.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(-0.8,2.1,9.1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(7.1,2.1,9.1)) ); - } + } void testSphereWithDefaultCentre() { @@ -365,125 +365,125 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( !shape_sptr->isValid(V3D( 0.0, 0.0,-1.1)) ); } - void testCylinder() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testCylinder() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,10)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.05,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.15,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.01,0.01,1)) ); - } + } - void testCylinderNoAlgebraString() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; + void testCylinderNoAlgebraString() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,10)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.05,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.15,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.01,0.01,1)) ); - } - - void testCylinderTwoAlgebraStrings() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; - xmlShape += " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); + } + + void testCylinderTwoAlgebraStrings() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; + xmlShape += " "; + + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,10)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.05,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.15,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.01,0.01,1)) ); - } + } - void testInfiniteCylinder() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testInfiniteCylinder() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,10)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.05,1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.15,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.01,0.01,1)) ); - } + } - void testCone() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testCone() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); + boost::shared_ptr shape_sptr = getObject(xmlShape); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,-1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.001,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.001,-1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.01,0.01,-1)) ); - } - - void testConeUseDirectStringArgument() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; - - ShapeFactory sFactory; - boost::shared_ptr shape_sptr = sFactory.createShape(xmlShape); + } + + void testConeUseDirectStringArgument() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; + + ShapeFactory sFactory; + boost::shared_ptr shape_sptr = sFactory.createShape(xmlShape); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.0,-1)) ); TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.001,1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.0,0.001,-1)) ); TS_ASSERT( shape_sptr->isValid(V3D(0.01,0.01,-1)) ); - } + } void testComplement() { @@ -512,69 +512,69 @@ class ShapeFactoryTest : public CxxTest::TestSuite TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,0.51)) ); } - void testNoneExistingShape() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testNoneExistingShape() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object + boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); - } + } - void testTypingErrorInSubElement() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; + void testTypingErrorInSubElement() + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; - boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object + boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); - } + } void testTypingErrorInAttribute() - { - //algebra line is essential - std::string xmlShape = " "; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += " " ; - xmlShape += ""; - xmlShape += " "; - - boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object + { + //algebra line is essential + std::string xmlShape = " "; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += " " ; + xmlShape += ""; + xmlShape += " "; + + boost::shared_ptr shape_sptr = getObject(xmlShape); // should return empty object TS_ASSERT( !shape_sptr->isValid(V3D(0.0,0.0,1)) ); - } + } - boost::shared_ptr getObject(std::string xmlShape) + boost::shared_ptr getObject(std::string xmlShape) { - std::string shapeXML = " " + xmlShape + " "; + std::string shapeXML = " " + xmlShape + " "; - // Set up the DOM parser and parse xml string - DOMParser pParser; - Poco::AutoPtr pDoc = pParser.parseString(shapeXML); + // Set up the DOM parser and parse xml string + DOMParser pParser; + Poco::AutoPtr pDoc = pParser.parseString(shapeXML); - // Get pointer to root element - Element* pRootElem = pDoc->documentElement(); + // Get pointer to root element + Element* pRootElem = pDoc->documentElement(); - //convert into a Geometry object - ShapeFactory sFactory; - boost::shared_ptr shape_sptr = sFactory.createShape(pRootElem); + //convert into a Geometry object + ShapeFactory sFactory; + boost::shared_ptr shape_sptr = sFactory.createShape(pRootElem); return shape_sptr; } From a1b1c3a526ff7bde42cf3bde5d0b25c38b5e595e Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 13:19:54 -0500 Subject: [PATCH 112/118] Re #8487. Hold document object in AutoPtr instead of raw pointer. --- .../MantidGeometry/Instrument/InstrumentDefinitionParser.h | 2 +- .../Geometry/src/Instrument/InstrumentDefinitionParser.cpp | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h index fc5d7b3c3199..d2acd9b54d4d 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h @@ -208,7 +208,7 @@ namespace Geometry std::string m_instName; /// XML document loaded - Poco::XML::Document* pDoc; + Poco::AutoPtr pDoc; /// Root element of the parsed XML Poco::XML::Element* pRootElem; diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index fd146f1a8e25..e20d03b6ce77 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -70,11 +70,6 @@ namespace Geometry */ InstrumentDefinitionParser::~InstrumentDefinitionParser() { - if (pDoc) - { - // release XML document - pDoc->release(); - } } //---------------------------------------------------------------------------------------------- @@ -170,7 +165,7 @@ namespace Geometry { return m_xmlFile->getMangledName(); } - else if (pDoc != NULL) + else if ( ! pDoc.isNull() ) { std::string lastModified = pRootElem->getAttribute("last-modified"); if (lastModified.empty()) From 6befd24c8e5a503f0877a3cbdbdab728422eb72a Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 13:20:14 -0500 Subject: [PATCH 113/118] Re #8487. Minimize the number of headers included. --- .../Instrument/InstrumentDefinitionParser.h | 35 ++++++++++++++----- .../Instrument/InstrumentDefinitionParser.cpp | 15 -------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h index d2acd9b54d4d..9c90b88a31d5 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h @@ -1,21 +1,38 @@ #ifndef MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSER_H_ #define MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSER_H_ - + +#include +#include +#include #include "MantidKernel/System.h" -#include "MantidGeometry/IComponent.h" -#include -#include -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/ICompAssembly.h" #include "MantidKernel/Logger.h" -#include "MantidKernel/ProgressBase.h" +#include "MantidKernel/V3D.h" +#include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/IDFObject.h" +namespace Poco +{ +namespace XML +{ + class Document; + class Element; +} +} namespace Mantid { +namespace Kernel +{ + class ProgressBase; +} + namespace Geometry { + class ICompAssembly; + class IComponent; + class Instrument; + class ObjComponent; + class Object; /** Creates an instrument data from a XML instrument description file @@ -24,7 +41,7 @@ namespace Geometry @author Anders Markvardsen, ISIS, RAL @date 7/3/2008 - Copyright © 2007-2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + Copyright © 2007-2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory This file is part of Mantid. @@ -59,7 +76,7 @@ namespace Geometry void initialize(IDFObject_const_sptr xmlFile, IDFObject_const_sptr expectedCacheFile, const std::string & instName, const std::string & xmlText); /// Parse XML contents - Instrument_sptr parseXML(Kernel::ProgressBase * prog); + boost::shared_ptr parseXML(Kernel::ProgressBase * prog); /// Add/overwrite any parameters specified in instrument with param values specified in XML elements void setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pElem); diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index e20d03b6ce77..6a8690b2ddee 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -1,6 +1,4 @@ #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/Instrument/Component.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" @@ -9,17 +7,10 @@ #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h" #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h" -#include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ConfigService.h" -#include "MantidKernel/ConfigService.h" -#include "MantidKernel/DateAndTime.h" -#include "MantidKernel/Interpolation.h" -#include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/ProgressBase.h" -#include "MantidKernel/System.h" #include "MantidKernel/UnitFactory.h" #include -#include #include #include #include @@ -27,13 +18,7 @@ #include #include #include -#include -#include -#include #include -#include -#include -#include using namespace Mantid; using namespace Mantid::Kernel; From f18a6fe3da2aca7a52fac41e9bbf84b200c4f770 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 13:40:30 -0500 Subject: [PATCH 114/118] Re #8487. Replace manual calls to release with AutoPtr. --- .../Instrument/InstrumentDefinitionParser.cpp | 51 ++++++------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index 6a8690b2ddee..bd77d7c4862d 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -184,7 +184,7 @@ namespace Geometry const std::string filename = m_xmlFile->getFileFullPathStr(); - NodeList* pNL_type = pRootElem->getElementsByTagName("type"); + Poco::AutoPtr pNL_type = pRootElem->getElementsByTagName("type"); if ( pNL_type->length() == 0 ) { g_log.error("XML file: " + filename + "contains no type elements."); @@ -249,9 +249,8 @@ namespace Geometry std::string typeName = pTypeElem->getAttribute("name"); // In this loop only interested in types containing - NodeList* pNL_type_combine_into_one_shape = pTypeElem->getElementsByTagName("combine-components-into-one-shape"); + Poco::AutoPtr pNL_type_combine_into_one_shape = pTypeElem->getElementsByTagName("combine-components-into-one-shape"); const unsigned long nelements = pNL_type_combine_into_one_shape->length(); - pNL_type_combine_into_one_shape->release(); if ( nelements == 0 ) continue; @@ -272,10 +271,9 @@ namespace Geometry mapTypeNameToShape[typeName] = shapeCreator.createShape(pTypeElem); mapTypeNameToShape[typeName]->setName(static_cast(iType)); } - pNL_type->release(); // finished with handling // create hasParameterElement - NodeList* pNL_parameter = pRootElem->getElementsByTagName("parameter"); + Poco::AutoPtr pNL_parameter = pRootElem->getElementsByTagName("parameter"); unsigned long numParameter = pNL_parameter->length(); hasParameterElement.reserve(numParameter); @@ -294,7 +292,6 @@ namespace Geometry pNode = it.nextNode(); } - pNL_parameter->release(); hasParameterElement_beenSet = true; // See if any parameters set at instrument level @@ -435,7 +432,7 @@ namespace Geometry // parse converted output DOMParser pLocationsParser; - Document* pLocationsDoc; + Poco::AutoPtr pLocationsDoc; try { pLocationsDoc = pLocationsParser.parseString(xmlLocation); @@ -450,9 +447,9 @@ namespace Geometry if ( !pRootLocationsElem->hasChildNodes() ) { throw Kernel::Exception::InstrumentDefinitionError("No root element in XML string", xmlLocation); - } + } - NodeList* pNL_locInLocs = pRootLocationsElem->getElementsByTagName("location"); + Poco::AutoPtr pNL_locInLocs = pRootLocationsElem->getElementsByTagName("location"); unsigned long pNL_locInLocs_length = pNL_locInLocs->length(); for (unsigned long iInLocs = 0; iInLocs < pNL_locInLocs_length; iInLocs++) { @@ -466,8 +463,6 @@ namespace Geometry appendLeaf(parent, pLocInLocsElem, pCompElem, idList); } } - pNL_locInLocs->release(); - pLocationsDoc->release(); } @@ -930,7 +925,7 @@ namespace Geometry std::vector InstrumentDefinitionParser::buildExcludeList(const Poco::XML::Element* const location) { // check if sub-elements for this location and create new exclude list to pass on - NodeList* pNLexclude = location->getElementsByTagName("exclude"); + Poco::AutoPtr pNLexclude = location->getElementsByTagName("exclude"); unsigned long numberExcludeEle = pNLexclude->length(); std::vector newExcludeList; for (unsigned long i = 0; i < numberExcludeEle; i++) @@ -939,7 +934,6 @@ namespace Geometry if ( pExElem->hasAttribute("sub-part") ) newExcludeList.push_back(pExElem->getAttribute("sub-part")); } - pNLexclude->release(); return newExcludeList; } @@ -1381,14 +1375,12 @@ namespace Geometry { // test first if any elements - NodeList* pNL = pE->getElementsByTagName("id"); + Poco::AutoPtr pNL = pE->getElementsByTagName("id"); if ( pNL->length() == 0 ) { throw Kernel::Exception::InstrumentDefinitionError("No id subelement of idlist element in XML instrument file", filename); } - pNL->release(); - // get id numbers @@ -1891,7 +1883,7 @@ namespace Geometry */ void InstrumentDefinitionParser::setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pRootElem) { - NodeList* pNL_link = pRootElem->getElementsByTagName("component-link"); + Poco::AutoPtr pNL_link = pRootElem->getElementsByTagName("component-link"); unsigned long numberLinks = pNL_link->length(); @@ -1937,7 +1929,6 @@ namespace Geometry } } } - pNL_link->release(); } @@ -2106,25 +2097,23 @@ namespace Geometry throw Exception::InstrumentDefinitionError( "Argument to function adjust() must be a pointer to an XML element with tag name type." ); // check that there is a element in type - NodeList* pNLccioh = pElem->getElementsByTagName("combine-components-into-one-shape"); + Poco::AutoPtr pNLccioh = pElem->getElementsByTagName("combine-components-into-one-shape"); if ( pNLccioh->length() == 0 ) { throw Exception::InstrumentDefinitionError( std::string("Argument to function adjust() must be a pointer to an XML element with tag name type,") + " which contain a element."); } - pNLccioh->release(); // check that there is a element in type - NodeList* pNLalg = pElem->getElementsByTagName("algebra"); + Poco::AutoPtr pNLalg = pElem->getElementsByTagName("algebra"); if ( pNLalg->length() == 0 ) { throw Exception::InstrumentDefinitionError( std::string("An element must be part of a , which") + " includes a element. See www.mantidproject.org/IDF." ); } - pNLalg->release(); // check that there is a element in type - NodeList* pNL = pElem->getElementsByTagName("location"); + Poco::AutoPtr pNL = pElem->getElementsByTagName("location"); unsigned long numLocation = pNL->length(); if ( numLocation == 0 ) { @@ -2133,13 +2122,12 @@ namespace Geometry } // check if a is defined - NodeList* pNL_TransRot = pElem->getElementsByTagName("translate-rotate-combined-shape-to"); + Poco::AutoPtr pNL_TransRot = pElem->getElementsByTagName("translate-rotate-combined-shape-to"); Element* pTransRot = 0; if ( pNL_TransRot->length() == 1 ) { pTransRot = static_cast(pNL_TransRot->item(0)); } - pNL_TransRot->release(); // to convert all 's in type into elements, which are added // to pElem, and these 's are deleted after loop @@ -2191,7 +2179,7 @@ namespace Geometry } DOMParser pParser; - Document* pDoc; + Poco::AutoPtr pDoc; try { pDoc = pParser.parseString(cuboidStr); @@ -2206,10 +2194,8 @@ namespace Geometry Poco::AutoPtr fisse = (pElem->ownerDocument())->importNode(pCuboid, true); pElem->appendChild(fisse); - pDoc->release(); allComponentInType.insert(pCompElem); } - pNL->release(); // delete all found in pElem std::set::iterator it; @@ -2297,7 +2283,7 @@ namespace Geometry const std::string& cuboidName) { DOMParser pParser; - Document* pDoc; + Poco::AutoPtr pDoc; try { pDoc = pParser.parseString(cuboidXML); @@ -2312,8 +2298,6 @@ namespace Geometry std::string retVal = translateRotateXMLcuboid(comp, pCuboid,cuboidName); - pDoc->release(); - return retVal; } @@ -2688,21 +2672,18 @@ namespace Geometry setLocation(ass, pLocElem, m_angleConvertConst); - NodeList* pNL = pType->getElementsByTagName("location"); + Poco::AutoPtr pNL = pType->getElementsByTagName("location"); if ( pNL->length() == 0 ) { - pNL->release(); return pType->getAttribute("name"); } else if ( pNL->length() == 1 ) { Element* pElem = static_cast(pNL->item(0)); - pNL->release(); return getShapeCoorSysComp(ass, pElem, getTypeElement, endAssembly); } else { - pNL->release(); throw Exception::InstrumentDefinitionError( std::string("When using ") + " the containing component elements are not allowed to contain multiple nested components. See www.mantidproject.org/IDF." ); } From 38955ae37bc0253685b8a3997613bc24d761f37d Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 14:00:37 -0500 Subject: [PATCH 115/118] Re #8487. It seems that Windows wants this include. --- .../Framework/Geometry/test/InstrumentDefinitionParserTest.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h index 443ffa2f7e11..a54eb272900f 100644 --- a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h +++ b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h @@ -17,6 +17,7 @@ #include #include +#include using namespace Mantid; using namespace Mantid::Kernel; From 168e8c4b4d4b6c9caf2ddb49408ecf7c7fda5666 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 14:17:28 -0500 Subject: [PATCH 116/118] Re #8487. Put include in right place to make Windows happy. Also clear up a few unused headers. --- .../Geometry/test/InstrumentDefinitionParserTest.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h index a54eb272900f..0f4830d85851 100644 --- a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h +++ b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h @@ -2,28 +2,20 @@ #define MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSERTEST_H_ #include -#include "MantidKernel/Timer.h" -#include "MantidKernel/System.h" -#include -#include - +#include #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/Strings.h" -#include "MantidKernel/V3D.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidTestHelpers/ScopedFileHelper.h" #include #include -#include using namespace Mantid; using namespace Mantid::Kernel; using namespace Mantid::Geometry; -using Mantid::Kernel::ConfigService; -using Mantid::Kernel::Strings::loadFile; using namespace testing; using ScopedFileHelper::ScopedFile; From 8f5741a251943fb3a84c758e2856f39bc0611359 Mon Sep 17 00:00:00 2001 From: Russell Taylor Date: Thu, 6 Mar 2014 14:49:20 -0500 Subject: [PATCH 117/118] Re #8487. Give up and put the include back in the header. The strange thing is that my local Windows build was just fine... --- .../inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h | 2 +- .../Framework/Geometry/test/InstrumentDefinitionParserTest.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h index 9c90b88a31d5..3d2749435c06 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "MantidKernel/System.h" #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" @@ -14,7 +15,6 @@ namespace Poco { namespace XML { - class Document; class Element; } } diff --git a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h index 0f4830d85851..e5a3e0f6c8a4 100644 --- a/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h +++ b/Code/Mantid/Framework/Geometry/test/InstrumentDefinitionParserTest.h @@ -2,7 +2,6 @@ #define MANTID_GEOMETRY_INSTRUMENTDEFINITIONPARSERTEST_H_ #include -#include #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/Strings.h" From d2257d14eb55e62564374515ca6753163ad7c28f Mon Sep 17 00:00:00 2001 From: Alex Buts Date: Fri, 7 Mar 2014 12:38:37 +0000 Subject: [PATCH 118/118] refs #8557 Modified convToEnergy to show SNS/ISIS differences clearly There are no changes to how the code run, but it has been modified to allow clear separation between SNS and ISIS related workflows - these changes make the difference explicit and allow easily modify the code to run foreign reduction. --- .../Inelastic/DirectEnergyConversion.py | 132 ++++++++++++------ 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py b/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py index 8c58d316a9e7..058181c00378 100644 --- a/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py +++ b/Code/Mantid/scripts/Inelastic/DirectEnergyConversion.py @@ -289,13 +289,9 @@ def mono_sample(self, mono_run, ei_guess, white_run=None, map_file=None, # ------------------------------------------------------------------------------------------- # This actually does the conversion for the mono-sample and mono-vanadium runs # -# ------------------------------------------------------------------------------------------- - def _do_mono(self, data_ws, monitor_ws, result_name, ei_guess, +# ------------------------------------------------------------------------------------------- + def _do_mono_SNS(self, data_ws, monitor_ws, result_name, ei_guess, white_run=None, map_file=None, spectra_masks=None, Tzero=None): - """ - Convert units of a given workspace to deltaE, including possible - normalisation to a white-beam vanadium run. - """ # Special load monitor stuff. if (self.instr_name == "CNCS" or self.instr_name == "HYSPEC"): @@ -367,39 +363,36 @@ def _do_mono(self, data_ws, monitor_ws, result_name, ei_guess, bin_offset = -mon1_peak # For event mode, we are going to histogram in energy first, then go back to TOF - if (self.__facility == "SNS"): - if self.check_background== True: - # Extract the time range for the background determination before we throw it away - background_bins = "%s,%s,%s" % (self.bkgd_range[0] + bin_offset, (self.bkgd_range[1]-self.bkgd_range[0]), self.bkgd_range[1] + bin_offset) - Rebin(InputWorkspace=result_name,OutputWorkspace= "background_origin_ws",Params=background_bins) - # Convert to Et - ConvertUnits(InputWorkspace=result_name,OutputWorkspace= "_tmp_energy_ws", Target="DeltaE",EMode="Direct", EFixed=ei_value) - RenameWorkspace(InputWorkspace="_tmp_energy_ws",OutputWorkspace= result_name) - # Histogram - Rebin(InputWorkspace=result_name,OutputWorkspace= "_tmp_rebin_ws",Params= self.energy_bins, PreserveEvents=False) - RenameWorkspace(InputWorkspace="_tmp_rebin_ws",OutputWorkspace= result_name) - # Convert back to TOF - ConvertUnits(InputWorkspace=result_name,OutputWorkspace=result_name, Target="TOF",EMode="Direct", EFixed=ei_value) + if self.check_background== True: + # Extract the time range for the background determination before we throw it away + background_bins = "%s,%s,%s" % (self.bkgd_range[0] + bin_offset, (self.bkgd_range[1]-self.bkgd_range[0]), self.bkgd_range[1] + bin_offset) + Rebin(InputWorkspace=result_name,OutputWorkspace= "background_origin_ws",Params=background_bins) + + # Convert to Et + ConvertUnits(InputWorkspace=result_name,OutputWorkspace= "_tmp_energy_ws", Target="DeltaE",EMode="Direct", EFixed=ei_value) + RenameWorkspace(InputWorkspace="_tmp_energy_ws",OutputWorkspace= result_name) + # Histogram + Rebin(InputWorkspace=result_name,OutputWorkspace= "_tmp_rebin_ws",Params= self.energy_bins, PreserveEvents=False) + RenameWorkspace(InputWorkspace="_tmp_rebin_ws",OutputWorkspace= result_name) + # Convert back to TOF + ConvertUnits(InputWorkspace=result_name,OutputWorkspace=result_name, Target="TOF",EMode="Direct", EFixed=ei_value) if self.check_background == True: # Remove the count rate seen in the regions of the histograms defined as the background regions, if the user defined such region ConvertToDistribution(Workspace=result_name) - if (self.__facility == "SNS"): - CalculateFlatBackground(InputWorkspace="background_origin_ws",OutputWorkspace= "background_ws", + + CalculateFlatBackground(InputWorkspace="background_origin_ws",OutputWorkspace= "background_ws", StartX= self.bkgd_range[0] + bin_offset,EndX= self.bkgd_range[1] + bin_offset, WorkspaceIndexList= '',Mode= 'Mean',OutputMode= 'Return Background') - # Delete the raw data background region workspace - DeleteWorkspace("background_origin_ws") - # Convert to distribution to make it compatible with the data workspace (result_name). - ConvertToDistribution(Workspace="background_ws") - # Subtract the background - Minus(LHSWorkspace=result_name,RHSWorkspace= "background_ws",OutputWorkspace=result_name) - # Delete the determined background - DeleteWorkspace("background_ws") - else: - CalculateFlatBackground(InputWorkspace=result_name,OutputWorkspace=result_name, - StartX= self.bkgd_range[0] + bin_offset,EndX= self.bkgd_range[1] + bin_offset, - WorkspaceIndexList= '',Mode= 'Mean') + # Delete the raw data background region workspace + DeleteWorkspace("background_origin_ws") + # Convert to distribution to make it compatible with the data workspace (result_name). + ConvertToDistribution(Workspace="background_ws") + # Subtract the background + Minus(LHSWorkspace=result_name,RHSWorkspace= "background_ws",OutputWorkspace=result_name) + # Delete the determined background + DeleteWorkspace("background_ws") + ConvertFromDistribution(Workspace=result_name) # Normalise using the chosen method @@ -420,15 +413,69 @@ def _do_mono(self, data_ws, monitor_ws, result_name, ei_guess, Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= self.energy_bins,PreserveEvents=False) if self.apply_detector_eff: - if self.__facility == "SNS": - # Need to be in lambda for detector efficiency correction - ConvertUnits(InputWorkspace=result_name,OutputWorkspace= result_name, Target="Wavelength", EMode="Direct", EFixed=ei_value) - He3TubeEfficiency(InputWorkspace=result_name,OutputWorkspace=result_name) - ConvertUnits(InputWorkspace=result_name,OutputWorkspace= result_name, Target="DeltaE",EMode='Direct', EFixed=ei_value) - else: - DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) - self.log("_do_mono: finished DetectorEfficiencyCor for : "+result_name) + # Need to be in lambda for detector efficiency correction + ConvertUnits(InputWorkspace=result_name,OutputWorkspace= result_name, Target="Wavelength", EMode="Direct", EFixed=ei_value) + He3TubeEfficiency(InputWorkspace=result_name,OutputWorkspace=result_name) + ConvertUnits(InputWorkspace=result_name,OutputWorkspace= result_name, Target="DeltaE",EMode='Direct', EFixed=ei_value) + ############ + return + + def _do_mono_ISIS(self, data_ws, monitor_ws, result_name, ei_guess, + white_run=None, map_file=None, spectra_masks=None, Tzero=None): + + # Do ISIS stuff for Ei + # Both are these should be run properties really + ei_value, mon1_peak = self.get_ei(monitor_ws, result_name, ei_guess) + self.incident_energy = ei_value + + # As we've shifted the TOF so that mon1 is at t=0.0 we need to account for this in CalculateFlatBackground and normalisation + bin_offset = -mon1_peak + + if self.check_background == True: + # Remove the count rate seen in the regions of the histograms defined as the background regions, if the user defined such region + ConvertToDistribution(Workspace=result_name) + CalculateFlatBackground(InputWorkspace=result_name,OutputWorkspace=result_name, + StartX= self.bkgd_range[0] + bin_offset,EndX= self.bkgd_range[1] + bin_offset, + WorkspaceIndexList= '',Mode= 'Mean') + ConvertFromDistribution(Workspace=result_name) + + # Normalise using the chosen method + # TODO: This really should be done as soon as possible after loading + self.normalise(mtd[result_name], result_name, self.normalise_method, range_offset=bin_offset) + + + # This next line will fail the SystemTests + #ConvertUnits(result_ws, result_ws, Target="DeltaE",EMode='Direct', EFixed=ei_value) + # But this one passes... + ConvertUnits(InputWorkspace=result_name,OutputWorkspace=result_name, Target="DeltaE",EMode='Direct') + self.log("_do_mono: finished ConvertUnits for : "+result_name) + + + + if not self.energy_bins is None: + Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= self.energy_bins,PreserveEvents=False) + + if self.apply_detector_eff: + DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) + self.log("_do_mono: finished DetectorEfficiencyCor for : "+result_name) + ############# + return + + def _do_mono(self, data_ws, monitor_ws, result_name, ei_guess, + white_run=None, map_file=None, spectra_masks=None, Tzero=None): + """ + Convert units of a given workspace to deltaE, including possible + normalisation to a white-beam vanadium run. + """ + if (self.__facility == "SNS"): + self._do_mono_SNS(data_ws,monitor_ws,result_name,ei_guess, + white_run, map_file, spectra_masks, Tzero) + else: + self._do_mono_ISIS(data_ws,monitor_ws,result_name,ei_guess, + white_run, map_file, spectra_masks, Tzero) + + ####################### # Ki/Kf Scaling... if self.apply_kikf_correction: self.log('Start Applying ki/kf corrections to the workpsace : '+result_name) @@ -449,11 +496,12 @@ def _do_mono(self, data_ws, monitor_ws, result_name, ei_guess, if white_run is not None: white_ws = self.do_white(white_run, spectra_masks, map_file,None) result_ws /= white_ws - #result_ws = Divide(LHSWorkspace=result_ws,RHSWorkspace=white_ws,NotWarnOnZeroDivide='1'); + # Overall scale factor result_ws *= self.scale_factor return result_ws + #------------------------------------------------------------------------------- def convert_to_energy(self, mono_run, ei, white_run=None, mono_van=None,\