diff --git a/Code/Mantid/Build/CMake/FindJsonCPP.cmake b/Code/Mantid/Build/CMake/FindJsonCPP.cmake index c52d1418812b..a28f35fd3334 100644 --- a/Code/Mantid/Build/CMake/FindJsonCPP.cmake +++ b/Code/Mantid/Build/CMake/FindJsonCPP.cmake @@ -9,11 +9,6 @@ # JSONCPP_LIBRARY_DEBUG - library files for linking (debug version) # JSONCPP_LIBRARIES - All required libraries, including the configuration type -# Using unset here is a temporary hack to force FindJson to find the correct -# path in an incremental build. It should be removed a day or two after the -# branch introducing this is merged. -unset ( JSONCPP_INCLUDE_DIR CACHE ) - # Headers find_path ( JSONCPP_INCLUDE_DIR json/reader.h PATH_SUFFIXES jsoncpp ) diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index 543277381857..1380797cf915 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -221,6 +221,7 @@ set ( INC_FILES inc/MantidAPI/IPeakFunction.h inc/MantidAPI/IPeaksWorkspace.h inc/MantidAPI/IPowderDiffPeakFunction.h + inc/MantidAPI/IRemoteJobManager.h inc/MantidAPI/ISpectrum.h inc/MantidAPI/ISplittersWorkspace.h inc/MantidAPI/ITableWorkspace.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h new file mode 100644 index 000000000000..2035e271f89e --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -0,0 +1,280 @@ +#ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H +#define MANTID_KERNEL_IREMOTEJOBMANAGER_H + +#include "MantidAPI/DllConfig.h" +#include "MantidKernel/DateAndTime.h" + +namespace Mantid { +namespace API { +/** +Common interface to different remote job managers (job schedulers, web +services, etc. such as MOAB, Platform LSF, or SLURM). + +IremoteJobManager objects are (in principle) created via the +RemoteJobManagerFactory. There are several "remote algorithms" in +Mantid: Authenticate, SubmitRemoteJob, QueryRemoteJobStatus, +etc. These algorithms are meant to use this interface to the different +specific implementations. Or, from the opposite angle, the methods of +this interface provide the functionality required by the remote +algorithms in a generic way (with respect to different job schedulers +or underlying mechanisms to handle remote jobs). So-called remote job +manager classes can implement this interface to provide +specialisations for Platform LSF, SLURM, MOAB, the Mantid web service +API, etc. + +A typical sequence of calls when you use this interface would be: + +1) Authenticate/log-in (authenticate()) +2) Do transactions + +Where the sequence of calls within a transaction is: + +2.1) Start transaction (startRemoteTransaction()) +2.2) Do actions +2.3) Stop transaction (stopRemoteTransaction()) + +In 2.2, several types of actions are possible: +- Submit a job to run on the (remote) compute resource (submitRemoteJob()). +- Get status info for one or all jobs (queryRemoteJob() and +queryAllRemoteJobs()). +- Cancel a job (abortRemoteJob()). +- Get list of available files for a transaction on the compute resource +(queryRemoteFile()) +- Upload / download files ( uploadRemoteFile() and downloadRemoteFile()). + + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +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 IRemoteJobManager { +public: + virtual ~IRemoteJobManager(){}; + + /** + * Status and general information about jobs running on (remote) + * compute resources. + */ + struct RemoteJobInfo { + /// Job ID, usually assigned by a job scheduler as an integer + /// number or similar. + std::string id; + /// name of the job, whether given by the user or automatically + /// assigned by the job scheduler + std::string name; + /// Name of the script or executable. Depending on the specific + /// implementation, job scheduler, etc. this can be an + /// 'application' name, a script name or different ways of + /// specifying what is run + std::string runnableName; + /// Last status retrieved (typically: Pending, Running, Exited, + /// etc.). The values are implementation/job scheduler dependent. + std::string status; + /// ID of the transaction where this job is included + std::string transactionID; + /// Date-time of submission. No particular format can be assumed + /// from the specific remote job managers, and some of them may + /// not provide this info + Mantid::Kernel::DateAndTime submitDate; + /// Date-time the job actually started running. No particular + /// format can be assumed + Mantid::Kernel::DateAndTime startDate; + /// Date-time the job finished. No particular format can be + /// assumed + Mantid::Kernel::DateAndTime completionTime; + }; + + /** + * Authenticate or log-in, previous to submitting jobs, up/downloading, etc. + * + * @param username User name or credentials + * + * @param password Password (or other type of authentication token) + * string. + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error If authentication fails + */ + virtual void authenticate(const std::string &username, + const std::string &password) = 0; + + /** + * Submit a job (and implicitly request to start it) within a + * transaction. + * + * @param transactionID ID obtained from a startRemoteTransaction() + * + * @param runnable Name of the script or executable for the + * job. This can be a name or path to a file (implementation + * dependent). + * + * @param param Parameters for the job. This is implementation + * dependent and may be a list of command line options, the name of + * a script or configuration file, the contents of a script to run + * or configuration template, etc. For example, for the Mantid web + * service API, this is the content of a python script. + * + * @param taskName (optional) human readable name for this job. + * + * @param numNodes number of nodes to use (optional and dependent on + * implementation and compute resource) + * + * @parm coresPerNode number of cores to use in each node (optional + * and dependent on implemenation and compute resource) + * + * @return jobID string for the job started (if successful). + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error if job submission fails. + */ + virtual std::string + submitRemoteJob(const std::string &transactionID, const std::string &runnable, + const std::string ¶m, const std::string &taskName = "", + const int numNodes = 1, const int coresPerNode = 1) = 0; + + /** + * Get/download a file from the (remote) compute resource. + * + * @param transactionID ID obtained from a startRemoteTransaction() + * + * @param remoteFileName Name of file on the (remote) compute + * resource. This can be a full or relative path or a simple file + * name, depending on implementation. + * + * @param localFileName Where to place the downloaded file on the + * local machine. + * + * @throws std::invalid_argument If any of the inputs is not set + * properly. + * @throws std::runtime_error If the download operation fails + */ + virtual void downloadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) = 0; + + /** + * Get information (status etc.) for all running jobs on the remote + * compute resource + * + * @return Status and general info for all the jobs found on the + * (remote) compute resource. Each of them should come identified by + * its ID. + * + * @throws std::runtime_error If the query fails + */ + virtual std::vector queryAllRemoteJobs() const = 0; + + /** + * Get the list of files available for a transaction at the (remote) + * compute resource. + * + * @param transactionID ID obtained from startRemoteTransaction() + * + * @return The names of all the available files + * + * @throws std::invalid_argument If there's an issue with the + * transaction ID + * + * @throws std::runtime_error If the query fails + */ + virtual std::vector + queryRemoteFile(const std::string &transactionID) const = 0; + + /** + * Get information (status etc.) for an (in principle) running job + * + * @param jobID ID of a job as obtained from submitRemoteJob() + * + * @return Status and general info for the job requested + * + * @throws std::invalid_argument If there's an issue with the + * job ID + * + * @throws std::runtime_error If the query fails + */ + virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const = 0; + + /** + * Start a transaction before up/downloading files and submitting + * jobs + * + * @return ID of the transaction as produced by the job scheduler + * and/or remote job manager. + * + * @throws std::runtime_error If the transaction creation fails + */ + virtual std::string startRemoteTransaction() = 0; + + /** + * Finish a transaction. This implicitly can cancel all the + * operations (jobs) associated with this transaction. + * + * @param transactionID An Id of a transaction, as returned by + * startRemoteTransaction() + * + * @throws std::invalid_argument If there's an issue with the + * transaction ID + * + * @throws std::runtime_error If the stop operation fails + */ + virtual void stopRemoteTransaction(const std::string &transactionID) = 0; + + /** + * Cancel a job (expected to be currently running on the remote resource) + * + * @param jobID ID for a job in a transaction, as returned by + * submitRemoteJob() + * + * @throws std::invalid_argument If there's an issue with the + * job ID + * @throws std::runtime_error If the abort/cancel operation fails + */ + virtual void abortRemoteJob(const std::string &jobID) = 0; + + /** + * Upload file for a transaction on the rmeote compute resource + * + * @param transactionID ID, as you get them from + * startRemoteTransaction() + * + * @param remoteFileName Name of file on the (remote) compute + * resource. This can be a full or relative path or a simple file + * name, depending on implementation. + * + * @param localFileName Path to the file to upload + * + * @throws std::invalid_argument If there's an issue with the + * arguments passed + * @throws std::runtime_error If the upload fails + */ + virtual void uploadRemoteFile(const std::string &transactionID, + const std::string &remoteFileName, + const std::string &localFileName) = 0; +}; + +// shared pointer type for the IRemoteJobManager +typedef boost::shared_ptr IRemoteJobManager_sptr; + +} // namespace API +} // namespace Mantid + +#endif // MANTID_API_IREMOTEJOBMANAGER_H diff --git a/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h b/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h index ea8ebf25defd..e1c508f64249 100644 --- a/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h +++ b/Code/Mantid/Framework/Algorithms/test/PolarizationCorrectionTest.h @@ -178,6 +178,7 @@ class PolarizationCorrectionTest: public CxxTest::TestSuite checkAlg->setChild(true); checkAlg->setProperty("Workspace1", groupWS->getItem(i)); checkAlg->setProperty("Workspace2", outWS->getItem(i)); + checkAlg->setProperty("Tolerance", 3e-16); checkAlg->execute(); const std::string result = checkAlg->getProperty("Result"); TS_ASSERT_EQUALS("Success!", result); diff --git a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp index 79f0d3da50ea..106ed965dab2 100644 --- a/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp +++ b/Code/Mantid/Framework/Crystal/src/SCDCalibratePanels.cpp @@ -1669,7 +1669,7 @@ void SCDCalibratePanels::FixUpBankParameterMap( void writeXmlParameter(ofstream &ostream, const string &name, const double value) { ostream << " " << endl; + << "\" /> " << endl; } void diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 4b7bae69801a..d19e1e94fada 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -24,6 +24,111 @@ void DynamicKuboToyabe::init() declareParameter("Nu", 0.0, "Hopping rate"); } + +//-------------------------------------------------------------------------------------------------------------------------------------- +// From Numerical Recipes + +// Midpoint method +double midpnt(double func(const double, const double, const double), + const double a, const double b, const int n, const double g, const double w0) { +// quote & modified from numerical recipe 2nd edtion (page147) + + static double s; + + if (n==1) { + s = (b-a)*func(0.5*(a+b),g,w0); + return (s); + } else { + double x, tnm, sum, del, ddel; + int it, j; + for (it=1,j=1;j c(n+1); + std::vector d(n+1); + for (i=1;i<=n;i++){ + double dift; + if((dift=fabs(x-xa[i]))= K) { + polint(&h[j-K],&s[j-K],K,0.0,ss,dss); + if (fabs(dss) <= fabs(ss)) return ss; + } + h[j+1]=h[j]/9.0; + } + throw std::runtime_error("Too many steps in routine integrate"); + return 0.0; +} + +// End of Numerical Recipes routines +//-------------------------------------------------------------------------------------------------------------------------------------- + + +// f1: function to integrate +double f1(const double x, const double G, const double w0) { + return( exp(-G*G*x*x/2)*sin(w0*x)); +} + // Static Zero Field Kubo Toyabe relaxation function double ZFKT (const double x, const double G){ @@ -31,33 +136,78 @@ double ZFKT (const double x, const double G){ return (0.3333333333 + 0.6666666667*exp(-0.5*q)*(1-q)); } +// Static non-zero field Kubo Toyabe relaxation function +double HKT (const double x, const double G, const double F) { + + const double q = G*G*x*x; + const double gm = 2*M_PI*0.01355342; // Muon gyromagnetic ratio * 2 * PI + + double w; + if (F>2*G) { + // Use F + w = gm * F; + } else { + // Use G + w = gm * 2 * G; + } + + const double r = G*G/w/w; + + double ig; + if ( x>0 && r>0 ) { + // Compute integral + ig = integral(f1,0.0,x,G,w); + } else { + // Integral is 0 + ig = 0; + } + + const double ktb=(1-2*r*(1-exp(-q/2)*cos(w*x))+2*r*r*w*ig); + + if ( F>2*G ) { + return ktb; + } else { + const double kz = ZFKT(x,G); + return kz+F/2/G*(ktb-kz); + } + +} + // Dynamic Kubo-Toyabe -double getDKT (double t, double G, double v){ +double getDKT (double t, double G, double F, double v){ const int tsmax = 656; // Length of the time axis, 32 us of valid data const double eps = 0.05; // Bin width for calculations - static double oldG=-1., oldV=-1.; + static double oldG=-1., oldV=-1., oldF=-1.; static std::vector gStat(tsmax), gDyn(tsmax); - if ( (G != oldG) || (v != oldV) ){ + if ( (G != oldG) || (v != oldV) || (F != oldF) ){ - // If G or v have changed with respect to the + // If G or v or F have changed with respect to the // previous call, we need to re-do the computations - if ( G != oldG ){ + if ( G != oldG || (F != oldF) ){ // But we only need to - // re-compute gStat if G has changed + // re-compute gStat if G or F have changed // Generate static Kubo-Toyabe - for (int k=0; k(); diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py index 3e5ecae529fc..563c56c6ccad 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py @@ -57,9 +57,6 @@ def PyInit(self): def PyExec(self): - from IndirectCommon import StartTime, EndTime - - StartTime('Symmetrise') self._setup() temp_ws_name = '__symm_temp' @@ -173,8 +170,6 @@ def PyExec(self): self.setProperty('OutputWorkspace', self._output_workspace) - EndTime('Symmetrise') - def validateInputs(self): """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py index ce5d2aa46a29..3d9a00cb0c2a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py @@ -1,6 +1,6 @@ from mantid.simpleapi import * -from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress -from mantid.kernel import StringMandatoryValidator, Direction, logger +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress, WorkspaceGroupProperty +from mantid.kernel import StringMandatoryValidator, Direction, logger, IntBoundedValidator, FloatBoundedValidator class IndirectAnnulusAbsorption(DataProcessorAlgorithm): @@ -14,46 +14,71 @@ def summary(self): def PyInit(self): + # Sample options self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), doc='Sample workspace.') + self.declareProperty(name='SampleChemicalFormula', defaultValue='', + validator=StringMandatoryValidator(), + doc='Chemical formula for the sample') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleInnerRadius', defaultValue=0.2, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='SampleOuterRadius', defaultValue=0.25, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + + # Container options self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, direction=Direction.Input), doc='Container workspace.') - - self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data') - - self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), - doc='Chemical formula') - - self.declareProperty(name='CanInnerRadius', defaultValue=0.2, doc='Sample radius') - self.declareProperty(name='SampleInnerRadius', defaultValue=0.15, doc='Sample radius') - self.declareProperty(name='SampleOuterRadius', defaultValue=0.16, doc='Sample radius') - self.declareProperty(name='CanOuterRadius', defaultValue=0.22, doc='Sample radius') - self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density') - self.declareProperty(name='Events', defaultValue=5000, doc='Number of neutron events') - self.declareProperty(name='Plot', defaultValue=False, doc='Plot options') - + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Chemical formula for the can') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can number density') + self.declareProperty(name='CanInnerRadius', defaultValue=0.19, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='CanOuterRadius', defaultValue=0.26, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General options + self.declareProperty(name='Events', defaultValue=5000, + validator=IntBoundedValidator(0), + doc='Number of neutron events') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output options self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), doc='The output corrected workspace.') - self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output, - optional=PropertyMode.Optional), + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), doc='The corrections workspace for scattering and absorptions in sample.') def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() # Set up progress reporting - n_prog_reports = 4 - if self._can_ws is not None: - n_prog_reports += 2 - prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports) + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) - prog_reporter.report('Processing sample') efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' @@ -61,71 +86,136 @@ def PyExec(self): Target='Wavelength', EMode='Indirect', EFixed=efixed) sample_thickness = self._sample_outer_radius - self._sample_inner_radius + logger.information('Sample thickness: ' + str(sample_thickness)) - prog_reporter.report('Calculating sample corrections') + prog.report('Calculating sample corrections') AnnularRingAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=3.0, SampleThickness=sample_thickness, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._can_outer_radius, - SampleChemicalFormula=self._chemical_formula, - SampleNumberDensity=self._number_density, + SampleChemicalFormula=self._sample_chemical_formula, + SampleNumberDensity=self._sample_number_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) - plot_list = [self._output_ws, self._sample_ws_name] + plot_data = [self._output_ws, self._sample_ws_name] + plot_corr = [self._ass_ws] + group = self._ass_ws - if self._can_ws is not None: - prog_reporter.report('Processing can') - can_wave_ws = '__can_wave' - ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws, + if self._can_ws_name is not None: + can1_wave_ws = '__can1_wave' + can2_wave_ws = '__can2_wave' + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can1_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) - if self._can_scale != 1.0: logger.information('Scaling can by: ' + str(self._can_scale)) - Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') + Scale(InputWorkspace=can1_wave_ws, OutputWorkspace=can1_wave_ws, Factor=self._can_scale, Operation='Multiply') + CloneWorkspace(InputWorkspace=can1_wave_ws, OutputWorkspace=can2_wave_ws) + + can_thickness_1 = self._sample_inner_radius - self._can_inner_radius + can_thickness_2 = self._can_outer_radius - self._sample_outer_radius + logger.information('Can thickness: %f & %f' % (can_thickness_1, can_thickness_2)) + + if self._use_can_corrections: + prog.report('Calculating container corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can1_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can1_wave_ws, + OutputWorkspace='__Acc1', + SampleHeight=3.0, + SampleThickness=can_thickness_1, + CanInnerRadius=self._can_inner_radius, + CanOuterRadius=self._sample_outer_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + SetSampleMaterial(can2_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can2_wave_ws, + OutputWorkspace='__Acc2', + SampleHeight=3.0, + SampleThickness=can_thickness_2, + CanInnerRadius=self._sample_inner_radius, + CanOuterRadius=self._can_outer_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + Multiply(LHSWorkspace='__Acc1', RHSWorkspace='__Acc2', OutputWorkspace=self._acc_ws) + DeleteWorkspace('__Acc1') + DeleteWorkspace('__Acc2') + + Divide(LHSWorkspace=can1_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can1_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws - prog_reporter.report('Applying can corrections') - Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) - DeleteWorkspace(can_wave_ws) + else: + prog.report('Calculating can scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) - plot_list.append(self._can_ws) + DeleteWorkspace(can1_wave_ws) + DeleteWorkspace(can2_wave_ws) + plot_data.append(self._can_ws_name) - prog_reporter.report('Applying corrections') - Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) - ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', - EMode='Indirect', EFixed=efixed) + else: + Divide(LHSWorkspace=sample_wave_ws, + RHSWorkspace=self._ass_ws, + OutputWorkspace=sample_wave_ws) + + ConvertUnits(InputWorkspace=sample_wave_ws, + OutputWorkspace=self._output_ws, + Target='DeltaE', + EMode='Indirect', + EFixed=efixed) DeleteWorkspace(sample_wave_ws) - prog_reporter.report('Recording sample logs') - sample_logs = {'sample_shape': 'annulus', - 'sample_filename': self._sample_ws_name, - 'sample_inner': self._sample_inner_radius, - 'sample_outer': self._sample_outer_radius, - 'can_inner': self._can_inner_radius, - 'can_outer': self._can_outer_radius} - addSampleLogs(self._ass_ws, sample_logs) - addSampleLogs(self._output_ws, sample_logs) - - if self._can_ws is not None: - AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + prog.report('Recording sample logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'annulus'), + ('sample_filename', self._sample_ws_name), + ('sample_inner', self._sample_inner_radius), + ('sample_outer', self._sample_outer_radius), + ('can_inner', self._can_inner_radius), + ('can_outer', self._can_outer_radius)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_thickness_1', can_thickness_1)) + sample_logs.append(('can_thickness_2', can_thickness_2)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not - if self._ass_ws == '_ass': + if self._abs_ws == '': DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) else: - self.setProperty('CorrectionsWorkspace', self._ass_ws) + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) if self._plot: from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() - mantid_plot.plotSpectrum(plot_list, 0) + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) def _setup(self): @@ -134,24 +224,59 @@ def _setup(self): """ self._sample_ws_name = self.getPropertyValue('SampleWorkspace') - self._can_scale = self.getProperty('CanScaleFactor').value - self._chemical_formula = self.getPropertyValue('ChemicalFormula') - self._number_density = self.getProperty('SampleNumberDensity').value - self._can_inner_radius = self.getProperty('CanInnerRadius').value + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value self._sample_inner_radius = self.getProperty('SampleInnerRadius').value self._sample_outer_radius = self.getProperty('SampleOuterRadius').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_inner_radius = self.getProperty('CanInnerRadius').value self._can_outer_radius = self.getProperty('CanOuterRadius').value + self._can_scale = self.getProperty('CanScaleFactor').value + self._events = self.getProperty('Events').value self._plot = self.getProperty('Plot').value self._output_ws = self.getPropertyValue('OutputWorkspace') - self._ass_ws = self.getPropertyValue('CorrectionsWorkspace') - if self._ass_ws == '': + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' + + # Geometry validation: can inner < sample inner < sample outer < can outer + if self._sample_inner_radius < self._can_inner_radius: + issues['SampleInnerRadius'] = 'Must be greater than CanInnerRadius' + + if self._sample_outer_radius < self._sample_inner_radius: + issues['SampleOuterRadius'] = 'Must be greater than SampleInnerRadius' + + if self._can_outer_radius < self._sample_outer_radius: + issues['CanOuterRadius'] = 'Must be greater than SampleOuterRadius' - self._can_ws = self.getPropertyValue('CanWorkspace') - if self._can_ws == '': - self._can_ws = None + return issues # Register algorithm with Mantid diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index d22e65e04404..c413199a8992 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -1,10 +1,28 @@ from mantid.simpleapi import * -from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress -from mantid.kernel import StringMandatoryValidator, Direction, logger +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceGroupProperty, PropertyMode, Progress +from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator, IntBoundedValidator class IndirectCylinderAbsorption(DataProcessorAlgorithm): + _sample_ws_name = None + _sample_chemical_formula = None + _sample_number_density = None + _sample_radius = None + _can_ws_name = None + _use_can_corrections = None + _can_chemical_formula = None + _can_number_density = None + _can_radius = None + _can_scale = None + _events = None + _plot = None + _output_ws = None + _abs_ws = None + _ass_ws = None + _acc_ws = None + + def category(self): return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" @@ -14,109 +32,172 @@ def summary(self): def PyInit(self): + # Sample options self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), doc='Sample workspace.') - + self.declareProperty(name='SampleChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), + doc='Sample chemical formula') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleRadius', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample radius') + + # Container options self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, direction=Direction.Input), doc='Container workspace.') - - self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data') - - self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), - doc='Chemical formula') - - self.declareProperty(name='SampleRadius', defaultValue=0.5, doc='Sample radius') - self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density') - self.declareProperty(name='Plot', defaultValue=False, doc='Plot options') - + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Can chemical formula') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can number density') + self.declareProperty(name='CanRadius', defaultValue=0.2, + validator=FloatBoundedValidator(0.0), + doc='Can radius') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General options + self.declareProperty(name='Events', defaultValue=5000, + validator=IntBoundedValidator(0), + doc='Number of neutron events') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output options self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), doc='The output corrected workspace.') - self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output, - optional=PropertyMode.Optional), + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), doc='The corrections workspace for scattering and absorptions in sample.') def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() # Set up progress reporting - n_prog_reports = 4 - if self._can_ws is not None: - n_prog_reports += 2 - prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports) + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) - prog_reporter.report('Processing sample') - efixed = getEfixed(self._sample_ws) + efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' - ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, + ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) - SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._number_density) + SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) - prog_reporter.report('Calculating sample corrections') + prog.report('Calculating sample corrections') CylinderAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, - SampleNumberDensity=self._number_density, + SampleNumberDensity=self._sample_number_density, NumberOfWavelengthPoints=10, CylinderSampleHeight=3.0, CylinderSampleRadius=self._sample_radius, NumberOfSlices=1, NumberOfAnnuli=10) - plot_list = [self._output_ws, self._sample_ws] + plot_data = [self._output_ws, self._sample_ws_name] + plot_corr = [self._ass_ws] + group = self._ass_ws - if self._can_ws is not None: - prog_reporter.report('Processing can') + if self._can_ws_name is not None: can_wave_ws = '__can_wave' - ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws, + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) - if self._can_scale != 1.0: logger.information('Scaling can by: ' + str(self._can_scale)) Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') - prog_reporter.report('Applying can corrections') - Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + can_thickness = self._can_radius - self._sample_radius + logger.information('Can thickness: ' + str(can_thickness)) + + if self._use_can_corrections: + # Doing can corrections + prog.report('Calculating can corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + AnnularRingAbsorption(InputWorkspace=can_wave_ws, + OutputWorkspace=self._acc_ws, + SampleHeight=3.0, + SampleThickness=can_thickness, + CanInnerRadius=0.9*self._sample_radius, + CanOuterRadius=1.1*self._can_radius, + SampleChemicalFormula=self._can_chemical_formula, + SampleNumberDensity=self._can_number_density, + NumberOfWavelengthPoints=10, + EventsPerPoint=self._events) + + Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws + + else: + # Doing simple can subtraction + prog.report('Calculating can scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + DeleteWorkspace(can_wave_ws) + plot_data.append(self._can_ws_name) - plot_list.append(self._can_ws) + else: + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) - prog_reporter.report('Applying corrections') - Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed) DeleteWorkspace(sample_wave_ws) - prog_reporter.report('Recording sample logs') - sample_logs = {'sample_shape': 'cylinder', - 'sample_filename': self._sample_ws, - 'sample_radius': self._sample_radius} - addSampleLogs(self._ass_ws, sample_logs) - addSampleLogs(self._output_ws, sample_logs) + # Record sample logs + prog.report('Recording sample logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'cylinder'), + ('sample_filename', self._sample_ws_name), + ('sample_radius', self._sample_radius)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_thickness', can_thickness)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] - if self._can_ws is not None: - AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) self.setProperty('OutputWorkspace', self._output_ws) - # Output the Ass workspace if it is wanted, delete if not - if self._ass_ws == '_ass': + # Output the Abs group workspace if it is wanted, delete if not + if self._abs_ws == '': DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) + else: - self.setProperty('CorrectionsWorkspace', self._ass_ws) + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) if self._plot: from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() - mantid_plot.plotSpectrum(plot_list, 0) + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) def _setup(self): @@ -124,21 +205,53 @@ def _setup(self): Get algorithm properties. """ - self._sample_ws = self.getPropertyValue('SampleWorkspace') - self._can_scale = self.getProperty('CanScaleFactor').value - self._chemical_formula = self.getPropertyValue('ChemicalFormula') - self._number_density = self.getProperty('SampleNumberDensity').value + self._sample_ws_name = self.getPropertyValue('SampleWorkspace') + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value self._sample_radius = self.getProperty('SampleRadius').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_radius = self.getProperty('CanRadius').value + self._can_scale = self.getProperty('CanScaleFactor').value + + self._events = self.getPropertyValue('Events') self._plot = self.getProperty('Plot').value + self._output_ws = self.getPropertyValue('OutputWorkspace') - self._ass_ws = self.getPropertyValue('CorrectionsWorkspace') - if self._ass_ws == '': + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._sample_radius > self._can_radius: + issues['CanRadius'] = 'Must be greater than SampleRadius' + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' - self._can_ws = self.getPropertyValue('CanWorkspace') - if self._can_ws == '': - self._can_ws = None + return issues # Register algorithm with Mantid diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py index 0fb3e2c3fe04..4651084b326a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py @@ -1,10 +1,31 @@ from mantid.simpleapi import * -from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress -from mantid.kernel import StringMandatoryValidator, Direction, logger +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress, WorkspaceGroupProperty +from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator class IndirectFlatPlateAbsorption(DataProcessorAlgorithm): + _sample_ws = None + _sample_chemical_formula = None + _sample_number_density = None + _sample_height = None + _sample_width = None + _sample_thickness = None + _can_ws_name = None + _use_can_corrections = None + _can_chemical_formula = None + _can_number_density = None + _can_front_thickness = None + _can_back_thickness = None + _can_scale = None + _element_size = None + _plot = None + _output_ws = None + _abs_ws = None + _ass_ws = None + _acc_ws = None + + def category(self): return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" @@ -14,116 +35,179 @@ def summary(self): def PyInit(self): + # Sample self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input), - doc='Sample workspace.') - + doc='Sample workspace') + self.declareProperty(name='SampleChemicalFormula', defaultValue='', + validator=StringMandatoryValidator(), + doc='Chemical formula for the sample') + self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Sample number density') + self.declareProperty(name='SampleHeight', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Sample height') + self.declareProperty(name='SampleWidth', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Sample width') + self.declareProperty(name='SampleThickness', defaultValue=0.5, + validator=FloatBoundedValidator(0.0), + doc='Sample thickness') + + # Container self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional, direction=Direction.Input), - doc='Container workspace.') - - self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data') - - self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), - doc='Chemical formula') - - self.declareProperty(name='SampleHeight', defaultValue=1.0, doc='Sample height') - self.declareProperty(name='SampleWidth', defaultValue=1.0, doc='Sample width') - self.declareProperty(name='SampleThickness', defaultValue=0.1, doc='Sample thickness') - self.declareProperty(name='ElementSize', defaultValue=0.1, doc='Element size in mm') - self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density') - self.declareProperty(name='Plot', defaultValue=False, doc='Plot options') - + doc='Container workspace') + self.declareProperty(name='UseCanCorrections', defaultValue=False, + doc='Use can corrections in subtraction') + self.declareProperty(name='CanChemicalFormula', defaultValue='', + doc='Chemical formula for the Container') + self.declareProperty(name='CanNumberDensity', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Container number density') + self.declareProperty(name='CanFrontThickness', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can front thickness') + self.declareProperty(name='CanBackThickness', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Can back thickness') + self.declareProperty(name='CanScaleFactor', defaultValue=1.0, + validator=FloatBoundedValidator(0.0), + doc='Scale factor to multiply can data') + + # General + self.declareProperty(name='ElementSize', defaultValue=0.1, + validator=FloatBoundedValidator(0.0), + doc='Element size in mm') + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot options') + + # Output self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), - doc='The output corrected workspace.') + doc='The output corrected workspace') + + self.declareProperty(WorkspaceGroupProperty('CorrectionsWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), + doc='The workspace group to save correction factors') - self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output, - optional=PropertyMode.Optional), - doc='The corrections workspace for scattering and absorptions in sample.') def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() # Set up progress reporting - n_prog_reports = 4 - if self._can_ws is not None: - n_prog_reports += 2 - prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports) + n_prog_reports = 2 + if self._can_ws_name is not None: + n_prog_reports += 1 + prog = Progress(self, 0.0, 1.0, n_prog_reports) - prog_reporter.report('Processing sample') efixed = getEfixed(self._sample_ws) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) - SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._number_density) + SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) - prog_reporter.report('Calculating sample corrections') + prog.report('Calculating sample corrections') FlatPlateAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, - SampleThickness=self._sample_thichness, + SampleThickness=self._sample_thickness, ElementSize=self._element_size, EMode='Indirect', EFixed=efixed, NumberOfWavelengthPoints=10) - plot_list = [self._output_ws, self._sample_ws] + plot_data = [self._output_ws, self._sample_ws] + plot_corr = [self._ass_ws] + group = self._ass_ws - if self._can_ws is not None: - prog_reporter.report('Processing can') + if self._can_ws_name is not None: can_wave_ws = '__can_wave' - ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws, + ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) - if self._can_scale != 1.0: logger.information('Scaling can by: ' + str(self._can_scale)) Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') - prog_reporter.report('Applying can corrections') - Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + if self._use_can_corrections: + prog.report('Calculating container corrections') + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + + SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) + FlatPlateAbsorption(InputWorkspace=can_wave_ws, + OutputWorkspace=self._acc_ws, + SampleHeight=self._sample_height, + SampleWidth=self._sample_width, + SampleThickness=self._can_front_thickness + self._can_back_thickness, + ElementSize=self._element_size, + EMode='Indirect', + EFixed=efixed, + NumberOfWavelengthPoints=10) + + Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + plot_corr.append(self._acc_ws) + group += ',' + self._acc_ws + + else: + prog.report('Calculating container scaling') + Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) + DeleteWorkspace(can_wave_ws) + plot_data.append(self._can_ws_name) - plot_list.append(self._can_ws) + else: + Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) - prog_reporter.report('Applying corrections') - Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed) DeleteWorkspace(sample_wave_ws) - prog_reporter.report('Recording sample logs') - sample_logs = {'sample_shape': 'flatplate', - 'sample_filename': self._sample_ws, - 'sample_height': self._sample_height, - 'sample_width': self._sample_width, - 'sample_thickness': self._sample_thichness, - 'element_size': self._element_size} - addSampleLogs(self._ass_ws, sample_logs) - addSampleLogs(self._output_ws, sample_logs) - - if self._can_ws is not None: - AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws)) - AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + prog.report('Recording samle logs') + sample_log_workspaces = [self._output_ws, self._ass_ws] + sample_logs = [('sample_shape', 'flatplate'), + ('sample_filename', self._sample_ws), + ('sample_height', self._sample_height), + ('sample_width', self._sample_width), + ('sample_thickness', self._sample_thickness), + ('element_size', self._element_size)] + + if self._can_ws_name is not None: + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) + if self._use_can_corrections: + sample_log_workspaces.append(self._acc_ws) + sample_logs.append(('can_front_thickness', self. _can_front_thickness)) + sample_logs.append(('can_back_thickness', self. _can_back_thickness)) + + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + + for ws_name in sample_log_workspaces: + AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not - if self._ass_ws == '_ass': + if self._abs_ws == '': DeleteWorkspace(self._ass_ws) + if self._can_ws_name is not None and self._use_can_corrections: + DeleteWorkspace(self._acc_ws) else: - self.setProperty('CorrectionsWorkspace', self._ass_ws) + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) + self.setProperty('CorrectionsWorkspace', self._abs_ws) if self._plot: - prog_reporter.report('Plotting') from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() - mantid_plot.plotSpectrum(plot_list, 0) + mantid_plot.plotSpectrum(plot_data, 0) + if self._abs_ws != '': + mantid_plot.plotSpectrum(plot_corr, 0) def _setup(self): @@ -132,23 +216,50 @@ def _setup(self): """ self._sample_ws = self.getPropertyValue('SampleWorkspace') - self._can_scale = self.getProperty('CanScaleFactor').value - self._chemical_formula = self.getPropertyValue('ChemicalFormula') - self._number_density = self.getProperty('SampleNumberDensity').value + self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula') + self._sample_number_density = self.getProperty('SampleNumberDensity').value self._sample_height = self.getProperty('SampleHeight').value self._sample_width = self.getProperty('SampleWidth').value - self._sample_thichness = self.getProperty('SampleThickness').value + self._sample_thickness = self.getProperty('SampleThickness').value + + self._can_ws_name = self.getPropertyValue('CanWorkspace') + if self._can_ws_name == '': + self._can_ws_name = None + self._use_can_corrections = self.getProperty('UseCanCorrections').value + self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula') + self._can_number_density = self.getProperty('CanNumberDensity').value + self._can_front_thickness = self.getProperty('CanFrontThickness').value + self._can_back_thickness = self.getProperty('CanBackThickness').value + self._can_scale = self.getProperty('CanScaleFactor').value + self._element_size = self.getProperty('ElementSize').value self._plot = self.getProperty('Plot').value self._output_ws = self.getPropertyValue('OutputWorkspace') - self._ass_ws = self.getPropertyValue('CorrectionsWorkspace') - if self._ass_ws == '': + self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') + if self._abs_ws == '': self._ass_ws = '__ass' + self._acc_ws = '__acc' + else: + self._ass_ws = self._abs_ws + '_ass' + self._acc_ws = self._abs_ws + '_acc' + + + def validateInputs(self): + """ + Validate algorithm options. + """ + + self._setup() + issues = dict() + + if self._use_can_corrections and self._can_chemical_formula == '': + issues['CanChemicalFormula'] = 'Must be set to use can corrections' + + if self._use_can_corrections and self._can_ws_name is None: + issues['UseCanCorrections'] = 'Must specify a can workspace to use can corections' - self._can_ws = self.getPropertyValue('CanWorkspace') - if self._can_ws == '': - self._can_ws = None + return issues # Register algorithm with Mantid diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py index aee835a87736..39070394a695 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py @@ -77,13 +77,10 @@ def PyInit(self): def PyExec(self): from mantid import config, logger - from IndirectCommon import StartTime, EndTime import inelastic_indirect_reducer self._setup() - StartTime('InelasticIndirectReduction') - # Setup reducer reducer = inelastic_indirect_reducer.IndirectReducer() @@ -157,8 +154,6 @@ def PyExec(self): if self._plot_type != 'none': self._plot() - EndTime('InelasticIndirectReduction') - def validateInputs(self): """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py index 73e8140748ac..ca4277dad752 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py @@ -77,11 +77,8 @@ def validateInputs(self): def PyExec(self): - from IndirectCommon import StartTime, EndTime from IndirectDiffractionReduction import MSGDiffractionReducer - StartTime('MSGDiffractionReduction') - input_files = self.getProperty('InputFiles').value sum_files = self.getProperty('SumFiles').value individual_grouping = self.getProperty('IndividualGrouping').value @@ -119,7 +116,5 @@ def PyExec(self): GroupWorkspaces(InputWorkspaces=result_ws_list, OutputWorkspace=output_ws_group) self.setProperty('OutputWorkspace', output_ws_group) - EndTime('MSGDiffractionReduction') - AlgorithmFactory.subscribe(MSGDiffractionReduction) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py index 115a9f241e98..c03efb8664f6 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py @@ -17,22 +17,25 @@ def setUp(self): self._red_ws = red_ws - def _test_workspaces(self, corrected, ass): + def _test_workspaces(self, corrected, factor_group): """ Checks the units of the Ass and corrected workspaces. @param corrected Corrected workspace - @param ass Assc corrections workspace + @param factor_group WorkspaceGroup containing factors """ + # Test units of corrected workspace corrected_x_unit = corrected.getAxis(0).getUnit().unitID() self.assertEqual(corrected_x_unit, 'DeltaE') - ass_x_unit = ass.getAxis(0).getUnit().unitID() - self.assertEquals(ass_x_unit, 'Wavelength') + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') - ass_y_unit = ass.YUnitLabel() - self.assertEqual(ass_y_unit, 'Attenuation factor') + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') def test_sample_corrections_only(self): @@ -40,15 +43,13 @@ def test_sample_corrections_only(self): Tests corrections for the sample only. """ - corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, - ChemicalFormula='H2-O', - CanInnerRadius=0.2, - SampleInnerRadius=0.15, - SampleOuterRadius=0.16, - CanOuterRadius=0.22, - Events=200) + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + Events=200, + UseCanCorrections=False) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction(self): @@ -56,16 +57,14 @@ def test_sample_and_can_subtraction(self): Tests corrections for the sample and simple container subtraction. """ - corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - ChemicalFormula='H2-O', - CanInnerRadius=0.2, - SampleInnerRadius=0.15, - SampleOuterRadius=0.16, - CanOuterRadius=0.22, - Events=200) + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + Events=200, + UseCanCorrections=False) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction_with_scale(self): @@ -74,17 +73,32 @@ def test_sample_and_can_subtraction_with_scale(self): with can scale. """ - corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - CanInnerRadius=0.2, - SampleInnerRadius=0.15, - SampleOuterRadius=0.16, - CanOuterRadius=0.22, - Events=200) - - self._test_workspaces(corrected, ass) + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + Events=200, + UseCanCorrections=False) + + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_corrections(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + CanScaleFactor=0.8, + Events=200, + UseCanCorrections=True) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) if __name__ == '__main__': diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py index d97057f84b35..cf422a7a7553 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py @@ -17,22 +17,25 @@ def setUp(self): self._red_ws = red_ws - def _test_workspaces(self, corrected, ass): + def _test_workspaces(self, corrected, factor_group): """ Checks the units of the Ass and corrected workspaces. @param corrected Corrected workspace - @param ass Assc corrections workspace + @param factor_group WorkspaceGroup containing factors """ + # Test units of corrected workspace corrected_x_unit = corrected.getAxis(0).getUnit().unitID() self.assertEqual(corrected_x_unit, 'DeltaE') - ass_x_unit = ass.getAxis(0).getUnit().unitID() - self.assertEquals(ass_x_unit, 'Wavelength') + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') - ass_y_unit = ass.YUnitLabel() - self.assertEqual(ass_y_unit, 'Attenuation factor') + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') def test_sample_corrections_only(self): @@ -40,11 +43,12 @@ def test_sample_corrections_only(self): Tests corrections for the sample only. """ - corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, - ChemicalFormula='H2-O', - SampleRadius=0.2) + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + Events=500) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction(self): @@ -52,12 +56,14 @@ def test_sample_and_can_subtraction(self): Tests corrections for the sample and simple container subtraction. """ - corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - ChemicalFormula='H2-O', - SampleRadius=0.2) + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + SampleChemicalFormula='H2-O', + UseCanCorrections=False, + Events=500) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction_with_scale(self): @@ -66,13 +72,31 @@ def test_sample_and_can_subtraction_with_scale(self): with can scale. """ - corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - SampleRadius=0.2) + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + SampleChemicalFormula='H2-O', + UseCanCorrections=False, + Events=500) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_corrections(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws, + CanWorkspace=self._can_ws, + SampleChemicalFormula='H2-O', + CanChemicalFormula='V', + UseCanCorrections=True, + Events=500) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) if __name__ == '__main__': diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py index 829d8688e685..48a9dcc6c062 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py @@ -17,22 +17,25 @@ def setUp(self): self._red_ws = red_ws - def _test_workspaces(self, corrected, ass): + def _test_workspaces(self, corrected, factor_group): """ Checks the units of the Ass and corrected workspaces. @param corrected Corrected workspace - @param ass Assc corrections workspace + @param factor_group WorkspaceGroup containing factors """ + # Test units of corrected workspace corrected_x_unit = corrected.getAxis(0).getUnit().unitID() self.assertEqual(corrected_x_unit, 'DeltaE') - ass_x_unit = ass.getAxis(0).getUnit().unitID() - self.assertEquals(ass_x_unit, 'Wavelength') + # Test units of factor workspaces + for ws in factor_group: + x_unit = ws.getAxis(0).getUnit().unitID() + self.assertEquals(x_unit, 'Wavelength') - ass_y_unit = ass.YUnitLabel() - self.assertEqual(ass_y_unit, 'Attenuation factor') + y_unit = ws.YUnitLabel() + self.assertEqual(y_unit, 'Attenuation factor') def test_sample_corrections_only(self): @@ -40,14 +43,12 @@ def test_sample_corrections_only(self): Tests corrections for the sample only. """ - corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, - ChemicalFormula='H2-O', - SampleHeight=1, - SampleWidth=1, - SampleThickness=1, - ElementSize=1) + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + ElementSize=1) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction(self): @@ -55,15 +56,14 @@ def test_sample_and_can_subtraction(self): Tests corrections for the sample and simple container subtraction. """ - corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - ChemicalFormula='H2-O', - SampleHeight=1, - SampleWidth=1, - SampleThickness=1, - ElementSize=1) + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + ElementSize=1, + UseCanCorrections=False) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) def test_sample_and_can_subtraction_with_scale(self): @@ -72,16 +72,31 @@ def test_sample_and_can_subtraction_with_scale(self): with can scale. """ - corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, - CanWorkspace=self._can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - SampleHeight=1, - SampleWidth=1, - SampleThickness=1, - ElementSize=1) + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanScaleFactor=0.8, + ElementSize=1, + UseCanCorrections=False) - self._test_workspaces(corrected, ass) + self.assertEqual(fact.size(), 1) + self._test_workspaces(corrected, fact) + + + def test_sample_and_can_correction(self): + """ + Tests corrections for the sample and container. + """ + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=self._can_ws, + CanChemicalFormula='V', + ElementSize=1, + UseCanCorrections=True) + + self.assertEqual(fact.size(), 2) + self._test_workspaces(corrected, fact) if __name__ == '__main__': diff --git a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index 11df5295a6c6..1b5c6875f770 100644 --- a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -81,10 +81,8 @@ Workspace2D_sptr Create1DWorkspaceConstant(int size, double value, double error) { MantidVecPtr x1, y1, e1; x1.access().resize(size, 1); - y1.access().resize(size); - std::fill(y1.access().begin(), y1.access().end(), value); - e1.access().resize(size); - std::fill(y1.access().begin(), y1.access().end(), error); + y1.access().resize(size, value); + e1.access().resize(size, error); Workspace2D_sptr retVal(new Workspace2D); retVal->initialize(1, size, size); retVal->setX(0, x1); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp index 1a78ab4259ca..136de6465559 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp @@ -3,14 +3,13 @@ #include "MantidAPI/FunctionFactory.h" #include "MantidAPI/FunctionDomain1D.h" #include "MantidAPI/AlgorithmManager.h" +#include "MantidQtAPI/HelpWindow.h" #include -#include #include #include #include -#include #include @@ -206,8 +205,7 @@ namespace CustomInterfaces } void ALCBaselineModellingView::help() { - QDesktopServices::openUrl(QUrl(QString("http://www.mantidproject.org/") + - "Muon_ALC:_Baseline_Modelling")); + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp index fe2ac1ebdd82..1c10a0abf0a1 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp @@ -1,8 +1,8 @@ #include "MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h" -#include +#include "MantidQtAPI/HelpWindow.h" + #include -#include #include @@ -165,8 +165,7 @@ namespace CustomInterfaces void ALCDataLoadingView::help() { - QDesktopServices::openUrl(QUrl(QString("http://www.mantidproject.org/") + - "Muon_ALC:_Data_Loading")); + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); } void ALCDataLoadingView::setWaitingCursor() diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp index 04dd6ca471aa..d8183fe40bf2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCPeakFittingView.cpp @@ -1,7 +1,7 @@ #include "MantidQtCustomInterfaces/Muon/ALCPeakFittingView.h" -#include -#include +#include "MantidQtAPI/HelpWindow.h" + #include namespace MantidQt @@ -106,8 +106,7 @@ void ALCPeakFittingView::setPeakPicker(const IPeakFunction_const_sptr& peak) void ALCPeakFittingView::help() { - QDesktopServices::openUrl(QUrl(QString("http://www.mantidproject.org/") + - "Muon_ALC:_Peak_Fitting")); + MantidQt::API::HelpWindow::showCustomInterface(NULL, QString("Muon_ALC")); } } // namespace CustomInterfaces diff --git a/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst index 90eebc58ce6c..2f1343fcdcf6 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst @@ -10,11 +10,12 @@ Description ----------- Calculates and applies corrections for scattering abs absorption in a annular -sample for a run on an indirect inelastic instrument, optionally also performing -a simple can subtraction is a container workspace is provided. +sample for a run on an indirect inelastic instrument, optionally allowing for +the subtraction or corrections of the container. -The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings -attenuation factor for absorption and scattering in the sample. +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. Usage ----- @@ -28,36 +29,81 @@ Usage red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') - corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=red_ws, - CanWorkspace=can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - CanInnerRadius=0.2, - SampleInnerRadius=0.15, - SampleOuterRadius=0.16, - CanOuterRadius=0.22, - Events=200) + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + CanInnerRadius=0.19, + SampleInnerRadius=0.2, + SampleOuterRadius=0.25, + CanOuterRadius=0.26, + Events=200) + + ass = fact[0] print ('Corrected workspace is intensity against %s' % (corrected.getAxis(0).getUnit().caption())) - print ('Corrections workspace is %s against %s' + print ('Ass workspace is %s against %s' % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) - .. testcleanup:: SampleCorrectionsWithCanSubtraction DeleteWorkspace(red_ws) DeleteWorkspace(can_ws) DeleteWorkspace(corrected) - DeleteWorkspace(ass) + DeleteWorkspace(fact) **Output:** - .. testoutput:: SampleCorrectionsWithCanSubtraction Corrected workspace is intensity against Energy transfer - Corrections workspace is Attenuation factor against Wavelength + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectAnnulusAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanChemicalFormula='H2-O', + CanInnerRadius=0.19, + SampleInnerRadius=0.2, + SampleOuterRadius=0.25, + CanOuterRadius=0.26, + Events=200, + UseCanCorrections=True) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst index eb7c25150ad5..ef2b38b70409 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst @@ -9,12 +9,13 @@ Description ----------- -Calculates and applies corrections for scattering abs absorption in a +Calculates and applies corrections for scattering and absorption in a cylindrical sample for a run on an indirect inelastic instrument, optionally -also performing a simple can subtraction is a container workspace is provided. +allowing for the subtraction or corrections of the container. -The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings -attenuation factor for absorption and scattering in the sample. +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. Usage ----- @@ -28,32 +29,78 @@ Usage red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') - corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=red_ws, - CanWorkspace=can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - SampleRadius=0.2) + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + SampleRadius=0.2, + UseCanCorrections=False, + Events=100) + + ass = fact[0] print ('Corrected workspace is intensity against %s' % (corrected.getAxis(0).getUnit().caption())) - print ('Corrections workspace is %s against %s' + print ('Ass workspace is %s against %s' % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) - .. testcleanup:: SampleCorrectionsWithCanSubtraction DeleteWorkspace(red_ws) DeleteWorkspace(can_ws) DeleteWorkspace(corrected) - DeleteWorkspace(ass) + DeleteWorkspace(fact) **Output:** - .. testoutput:: SampleCorrectionsWithCanSubtraction - Corrected workspace is intensity against Energy transfer - Corrections workspace is Attenuation factor against Wavelength + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample and container corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectCylinderAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + SampleRadius=0.2, + CanWorkspace=can_ws, + CanScaleFactor=0.8, + CanChemicalFormula='V', + CanRadius=0.22, + UseCanCorrections=True, + Events=100) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst index 0557ecb326b9..7e83f5ec675d 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst @@ -10,11 +10,12 @@ Description ----------- Calculates and applies corrections for scattering abs absorption in a flat plate -sample for a run on an indirect inelastic instrument, optionally also performing -a simple can subtraction is a container workspace is provided. +sample for a run on an indirect inelastic instrument, optionally allowing for +the subtraction or corrections of the container. -The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings -attenuation factor for absorption and scattering in the sample. +The correction factor workspace is a workspace group containing the correction +factors in the Paalman and Pings format, note that only :math:`{A_{s,s}}` and +:math:`A_{c,c}` factors are calculated by thsi algorithm. Usage ----- @@ -28,35 +29,81 @@ Usage red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') - corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws, - CanWorkspace=can_ws, - CanScaleFactor=0.8, - ChemicalFormula='H2-O', - SampleHeight=1, - SampleWidth=1, - SampleThickness=1, - ElementSize=1) + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanScaleFactor=0.8, + SampleHeight=1, + SampleWidth=1, + SampleThickness=1, + ElementSize=1, + UseCanCorrections=False) + + ass = fact[0] print ('Corrected workspace is intensity against %s' % (corrected.getAxis(0).getUnit().caption())) - print ('Corrections workspace is %s against %s' + print ('Ass workspace is %s against %s' % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) - .. testcleanup:: SampleCorrectionsWithCanSubtraction DeleteWorkspace(red_ws) DeleteWorkspace(can_ws) DeleteWorkspace(corrected) - DeleteWorkspace(ass) + DeleteWorkspace(fact) **Output:** - .. testoutput:: SampleCorrectionsWithCanSubtraction - Corrected workspace is intensity against Energy transfer - Corrections workspace is Attenuation factor against Wavelength + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample and container corrections for IRIS:** + +.. testcode:: SampleAndCanCorrections + + red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') + can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') + + corrected, fact = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws, + SampleChemicalFormula='H2-O', + CanWorkspace=can_ws, + CanChemicalFormula='V', + CanScaleFactor=0.8, + SampleHeight=1, + SampleWidth=1, + SampleThickness=1, + ElementSize=1, + UseCanCorrections=True) + + ass = fact[0] + acc = fact[1] + + print ('Corrected workspace is intensity against %s' + % (corrected.getAxis(0).getUnit().caption())) + + print ('Ass workspace is %s against %s' + % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption())) + + print ('Acc workspace is %s against %s' + % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) + +.. testcleanup:: SampleAndCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleAndCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst index c64b003e7668..831d0c6d5d85 100644 --- a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -162,7 +162,7 @@ Usage **Example - IntegrateEllipsoids:** -The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own +The code itself works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** file is availible in `Mantid system tests repository `_. diff --git a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst index 704b3cf2ce53..20ec4aae8a90 100644 --- a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst +++ b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst @@ -129,7 +129,7 @@ Usage **Example - IntegratePeaks:** -The code iteslef works but disabled from doc tests as takes too long to complete. User should provide its own +The code itself works but disabled from doc tests as takes too long to complete. User should provide its own event nexus file instead of **TOPAZ_3132_event.nxs** used within this example. The original **TOPAZ_3132_event.nxs** file is availible in `Mantid system tests repository `_. diff --git a/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst b/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst index 0ddba6913fe7..1f98aa15a476 100644 --- a/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SCDCalibratePanels-v1.rst @@ -95,4 +95,17 @@ algorithm. To do so select the workspace, which you have calibrated as the InputWorkspace and the workspace you want to copy the calibration to, the OutputWorkspace. +Usage +------ + +**Example - SCDCalibratePanels:** + + LoadIsawPeaks(Filename='MANDI_801.peaks', OutputWorkspace='peaks') + SCDCalibratePanels(PeakWorkspace='peaks',DetCalFilename='mandi_801.DetCal',XmlFilename='mandi_801.xml',a=74,b=74.5,c=99.9,alpha=90,beta=90,gamma=60) + Load(Filename='MANDI_801_event.nxs', OutputWorkspace='MANDI_801_event') + CloneWorkspace(InputWorkspace='MANDI_801_event', OutputWorkspace='MANDI_801_event_xml') + LoadParameterFile(Workspace='MANDI_801_event_xml', Filename='mandi_801.xml') + RenameWorkspace(InputWorkspace='MANDI_801_event_xml', OutputWorkspace='MANDI_801_event_DetCal') + LoadIsawDetCal(InputWorkspace='MANDI_801_event_DetCal', Filename='mandi_801.DetCal') + .. categories:: diff --git a/Code/Mantid/docs/source/interfaces/Muon_ALC.rst b/Code/Mantid/docs/source/interfaces/Muon_ALC.rst new file mode 100644 index 000000000000..44496c7921e2 --- /dev/null +++ b/Code/Mantid/docs/source/interfaces/Muon_ALC.rst @@ -0,0 +1,124 @@ +Muon ALC +======== + +.. contents:: Table of Contents + :local: + +Overview +-------- + +The Muon ALC interface, which is short for Avoided Level Crossing, aims at +handling frequent analysis on e.g. HIFI. It uses simple point-and-click to +analyse a sequence of datasets collected with different parameter values, for +instance different magnetic fields, temperature, etc, and study how this +affects asymmetry. There are currently three steps in the analysis. + +Data Loading +------------ + +The Data Loading step, provides an interface for the +:ref:`PlotAsymmetryByLogValue ` algorithm, +in which a sequence of runs are loaded through the fields +*First* and *Last*. All datasets with run number between these limits will be +loaded, and an error message will be shown if any of them is missing. The +user must supply the log data that will be used as X parameter from the list +of available log values. + +.. interface:: ALC + :widget: dataLoadingView + :align: center + :width: 800 + +Options +~~~~~~~ + +First + First run of the sequence of datasets. + +Last + Last run of the sequence of datasets. + +Log + Log value to use as X parameter + +Dead Time Correction + Type of dead time corrections to apply. Options are *None*, in which case no + corrections will be applied, *From Data File*, to load corrections from + the input dataset itself, or *From Custom File*, to load corrections from a + specified nexus file. + +Grouping + Detector grouping to apply. *Auto* will load the grouping information contained + in the run file, while *Custom* allows to specify the list of spectra for both the + forward and backward groups. + +Periods + Period number to use as red data. The *Subtract* option, if checked, allows to + select the green period number that will be subtracted to the red data. + +Calculation + Type of calculation, *Integral* or *Differential*, together with the time limits. + +? + Shows this help page. + +Load + Computes the asymmetry according to selected options and displays it against the + chosen log value. + +Baseline Modelling +------------------ + +In the Baseline Modelling step, the user can fit the baseline by selecting which +sections of the data should be used in the fit, and what the baseline fit +function should be. To select a baseline function, right-click on the *Function* +region, then *Add function* and choose among the different possibilities. Then +pick the desired fitting sections. + +.. interface:: ALC + :widget: baselineModellingView + :align: center + :width: 400 + +Options +~~~~~~~ + +Function + Right-click on the blank area to add a baseline function. + +Sections + Right-click on the blank area to add as many sections as needed to + select the ranges to fit. + +? + Shows this help page. + +Fit + Fits the data. + +Peak Fitting +------------ + +In the Peak Fitting step, data with the baseline subtracted are shown in +the right panel. The user can study the peaks of interest all with the same simple +interface. To add a new peak, right-click on the Peaks region, then select +*Add function* and choose among the different possibilities in the category Peak. + +.. interface:: ALC + :widget: peakFittingView + :align: center + :width: 600 + +Options +~~~~~~~ + +Peaks + Right-click on the blank area to add a peak function. + +? + Shows this help page. + +Fit + Fits the data. + +.. categories:: Interfaces Muon diff --git a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py index bd2855548e4a..3f7b40f777eb 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py +++ b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py @@ -193,25 +193,28 @@ def AbsRun(inputWS, geom, beam, ncan, size, density, sigs, siga, avar, Save): accWS = name + '_acc' fname = name + '_abs' + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + CreateWorkspace(OutputWorkspace=assWS, DataX=dataX, DataY=dataA1, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(assWS, sample_logs) + AddSampleLogMultiple(Workspace=assWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=asscWS, DataX=dataX, DataY=dataA2, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(asscWS, sample_logs) + AddSampleLogMultiple(Workspace=asscWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=acscWS, DataX=dataX, DataY=dataA3, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(acscWS, sample_logs) + AddSampleLogMultiple(Workspace=acscWS, LogNames=log_names, LogValues=log_values) CreateWorkspace(OutputWorkspace=accWS, DataX=dataX, DataY=dataA4, NSpec=ndet, UnitX='Wavelength', VerticalAxisUnit=v_axis_unit, VerticalAxisValues=v_axis_values) - addSampleLogs(accWS, sample_logs) + AddSampleLogMultiple(Workspace=accWS, LogNames=log_names, LogValues=log_values) group = assWS + ',' + asscWS + ',' + acscWS + ',' + accWS GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fname) diff --git a/Code/Mantid/scripts/Inelastic/IndirectCommon.py b/Code/Mantid/scripts/Inelastic/IndirectCommon.py index 7804beeac9c0..b96219f3b30d 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectCommon.py +++ b/Code/Mantid/scripts/Inelastic/IndirectCommon.py @@ -545,23 +545,3 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam axis.setLabel(i, name) mtd[output_name].replaceAxis(1, axis) - -def addSampleLogs(ws, sample_logs): - """ - Add a dictionary of logs to a workspace. - - The type of the log is inferred by the type of the value passed to the log. - - @param ws - workspace to add logs too. - @param sample_logs - dictionary of logs to append to the workspace. - """ - - for key, value in sample_logs.iteritems(): - if isinstance(value, bool): - log_type = 'String' - elif isinstance(value, (int, long, float)): - log_type = 'Number' - else: - log_type = 'String' - - AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value)) diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index 54e34ca44457..c258965efba5 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -98,26 +98,28 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin axis = mtd[wsname].getAxis(0) axis.setUnit("MomentumTransfer") + # Handle sample logs + temp_correction = temperature is not None + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=wsname) - AddSampleLog(Workspace=wsname, LogName='convolve_members', - LogType='String', LogText=str(convolve)) - AddSampleLog(Workspace=wsname, LogName="fit_program", - LogType="String", LogText='ConvFit') - AddSampleLog(Workspace=wsname, LogName='background', - LogType='String', LogText=str(bgd)) - AddSampleLog(Workspace=wsname, LogName='delta_function', - LogType='String', LogText=str(using_delta_func)) - AddSampleLog(Workspace=wsname, LogName='lorentzians', - LogType='String', LogText=str(lorentzians)) - CopyLogs(InputWorkspace=wsname, OutputWorkspace=output_workspace + "_Workspaces") + sample_logs = [('convolve_members', convolve), + ('fit_program', 'ConvFit'), + ('background', bgd), + ('delta_function', using_delta_func), + ('lorentzians', lorentzians), + ('temperature_correction', temp_correction)] - temp_correction = temperature is not None - AddSampleLog(Workspace=wsname, LogName='temperature_correction', - LogType='String', LogText=str(temp_correction)) if temp_correction: - AddSampleLog(Workspace=wsname, LogName='temperature_value', - LogType='String', LogText=str(temperature)) + sample_logs.append(('temperature_value', temperature)) + + log_names = [log[0] for log in sample_logs] + log_values = [log[1] for log in sample_logs] + AddSampleLogMultiple(Workspace=wsname, + LogNames=log_names, + LogValues=log_values) + + CopyLogs(InputWorkspace=wsname, OutputWorkspace=output_workspace + "_Workspaces") RenameWorkspace(InputWorkspace=output_workspace, OutputWorkspace=output_workspace + "_Parameters") @@ -200,8 +202,10 @@ def furyfitSeq(inputWS, func, ftype, startx, endx, spec_min=0, spec_max=None, in CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) - addSampleLogs(fit_group, sample_logs) - addSampleLogs(result_workspace, sample_logs) + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + AddSampleLogMultiple(Workspace=result_workspace, LogNames=log_names, LogValues=log_values) + AddSampleLogMultiple(Workspace=fit_group, LogNames=log_names, LogValues=log_values) if Save: save_workspaces = [result_workspace, fit_group] @@ -270,8 +274,10 @@ def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=Non CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) - addSampleLogs(result_workspace, sample_logs) - addSampleLogs(fit_group, sample_logs) + log_names = [item[0] for item in sample_logs] + log_values = [item[1] for item in sample_logs] + AddSampleLogMultiple(Workspace=result_workspace, LogNames=log_names, LogValues=log_values) + AddSampleLogMultiple(Workspace=fit_group, LogNames=log_names, LogValues=log_values) DeleteWorkspace(tmp_fit_workspace) diff --git a/Code/Mantid/scripts/test/IndirectCommonTests.py b/Code/Mantid/scripts/test/IndirectCommonTests.py index 48b88d94cdbc..a0bbe462f142 100644 --- a/Code/Mantid/scripts/test/IndirectCommonTests.py +++ b/Code/Mantid/scripts/test/IndirectCommonTests.py @@ -285,23 +285,6 @@ def test_convertParametersToWorkspace(self): self.assert_matrix_workspace_dimensions(params_workspace.name(), expected_num_histograms=3, expected_blocksize=5) - def test_addSampleLogs(self): - ws = CreateSampleWorkspace() - logs = {} - logs['FloatLog'] = 3.149 - logs['IntLog'] = 42 - logs['StringLog'] = "A String Log" - logs['BooleanLog'] = True - - indirect_common.addSampleLogs(ws, logs) - - self.assert_logs_match_expected(ws.name(), logs) - - def test_addSampleLogs_empty_dict(self): - ws = CreateSampleWorkspace() - logs = {} - self.assert_does_not_raise(Exception, indirect_common.addSampleLogs, ws, logs) - #----------------------------------------------------------- # Custom assertion functions #-----------------------------------------------------------