From 8fc0b2d41c0a19e7a63c7d169079dcf2652fbde4 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Mon, 2 Mar 2015 13:55:36 +0000 Subject: [PATCH 01/37] Re #11086 Add static KT function for magnetic field --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 4b7bae69801a..294b36ed39cd 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -31,6 +31,43 @@ 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){ From 068b847d0751c17687b6d59f2e83668b7d657ad6 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Mon, 2 Mar 2015 13:58:31 +0000 Subject: [PATCH 02/37] Re #11086 Add function to integrate --- Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 294b36ed39cd..4c16701033df 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -24,6 +24,11 @@ void DynamicKuboToyabe::init() declareParameter("Nu", 0.0, "Hopping rate"); } +// 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){ From 9c15ca4edf8882e8eef5c78f462cc7fdac1c7788 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Mon, 2 Mar 2015 15:25:48 +0000 Subject: [PATCH 03/37] Re #11086 Add NR routines and update getDKT function --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 126 ++++++++++++++++-- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 4c16701033df..37a9f1cf2621 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -6,6 +6,10 @@ #include "MantidAPI/FunctionFactory.h" #include +#define JMAX 14 +#define JMAXP (JMAX+1) +#define K 5 + namespace Mantid { namespace CurveFitting @@ -24,6 +28,102 @@ 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; + } + std::cout << "integrate(): Too many steps in routine integrate\n" << std::endl; + 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)); @@ -74,32 +174,40 @@ double HKT (const double x, const double G, const double F) { } // 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 Date: Mon, 2 Mar 2015 15:29:16 +0000 Subject: [PATCH 04/37] Re #11086 Update fitting function for non zero field --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 37a9f1cf2621..32599d08835e 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -255,26 +255,19 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz } // Non-zero external field else{ - throw std::runtime_error("HKT() not implemented yet"); + for (size_t i = 0; i < nData; i++) { + out[i] = A*HKT(xValues[i],G,F); + } } } // Non-zero hopping rate else { - if ( F==0.0 ) { - - for (size_t i = 0; i Date: Mon, 16 Mar 2015 12:45:20 +0000 Subject: [PATCH 05/37] Added IRemoteJobManager interface, re #11123 --- Code/Mantid/Framework/Kernel/CMakeLists.txt | 1 + .../inc/MantidKernel/IRemoteJobManager.h | 276 ++++++++++++++++++ 2 files changed, 277 insertions(+) create mode 100644 Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt index 887bba027157..6f70ef56c341 100644 --- a/Code/Mantid/Framework/Kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt @@ -165,6 +165,7 @@ set ( INC_FILES inc/MantidKernel/InstrumentInfo.h inc/MantidKernel/InternetHelper.h inc/MantidKernel/Interpolation.h + inc/MantidKernel/IRemoteJobManager.h inc/MantidKernel/LibraryManager.h inc/MantidKernel/LibraryWrapper.h inc/MantidKernel/ListValidator.h diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h new file mode 100644 index 000000000000..99372b058fdd --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h @@ -0,0 +1,276 @@ +#ifndef IREMOTEJOBMANAGER_H +#define IREMOTEJOBMANAGER_H + +#include "MantidKernel/DllConfig.h" + +namespace Mantid { +namespace Kernel { +/** +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_KERNEL_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 + std::string submitDate; + /// Date-time the job actually started running. No particular + /// format can be assumed + std::string startDate; + /// Date-time the job finished. No particular format can be + /// assumed + std::string 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(std::string &username, 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() = 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) = 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) = 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 Kernel +} // namespace Mantid + +#endif // IREMOTEJOBMANAGER_H From 5bbc66e0524630201da57955e446e3efef6cd995 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Mon, 16 Mar 2015 12:58:07 +0000 Subject: [PATCH 06/37] Make the clear-cut const methods const, re #11123 --- .../Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h index 99372b058fdd..0314198e6dfc 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h @@ -177,7 +177,7 @@ class MANTID_KERNEL_DLL IRemoteJobManager { * * @throws std::runtime_error If the query fails */ - virtual std::vector queryAllRemoteJobs() = 0; + virtual std::vector queryAllRemoteJobs() const = 0; /** * Get the list of files available for a transaction at the (remote) @@ -193,7 +193,7 @@ class MANTID_KERNEL_DLL IRemoteJobManager { * @throws std::runtime_error If the query fails */ virtual std::vector - queryRemoteFile(const std::string &transactionID) = 0; + queryRemoteFile(const std::string &transactionID) const = 0; /** * Get information (status etc.) for an (in principle) running job @@ -207,7 +207,7 @@ class MANTID_KERNEL_DLL IRemoteJobManager { * * @throws std::runtime_error If the query fails */ - virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) = 0; + virtual RemoteJobInfo queryRemoteJob(const std::string &jobID) const = 0; /** * Start a transaction before up/downloading files and submitting From d3e3c0d10cb51fdcea89d6c4e41b150b5356239d Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Mon, 16 Mar 2015 17:00:24 +0000 Subject: [PATCH 07/37] more specific header define, re #11123 --- .../Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h index 0314198e6dfc..359619a09de1 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h @@ -1,5 +1,5 @@ -#ifndef IREMOTEJOBMANAGER_H -#define IREMOTEJOBMANAGER_H +#ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H +#define MANTID_KERNEL_IREMOTEJOBMANAGER_H #include "MantidKernel/DllConfig.h" @@ -273,4 +273,4 @@ typedef boost::shared_ptr IRemoteJobManager_sptr; } // namespace Kernel } // namespace Mantid -#endif // IREMOTEJOBMANAGER_H +#endif // MANTID_KERNEL_IREMOTEJOBMANAGER_H From db47165db5867b841dee0d610ef16e0267d7bd35 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Fri, 20 Mar 2015 12:15:36 +0000 Subject: [PATCH 08/37] add constness of auth method, and a std namespace, re #11123 --- .../API/inc/MantidAPI/IRemoteJobManager.h | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.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..8ee6dd776735 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -0,0 +1,277 @@ +#ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H +#define MANTID_KERNEL_IREMOTEJOBMANAGER_H + +#include "MantidKernel/DllConfig.h" + +namespace Mantid { +namespace Kernel { +/** +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_KERNEL_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 + std::string submitDate; + /// Date-time the job actually started running. No particular + /// format can be assumed + std::string startDate; + /// Date-time the job finished. No particular format can be + /// assumed + std::string 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 Kernel +} // namespace Mantid + +#endif // MANTID_KERNEL_IREMOTEJOBMANAGER_H From 4d7dae89acff799302f3b338306f47fec34fecce Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Fri, 20 Mar 2015 12:16:39 +0000 Subject: [PATCH 09/37] move the IRemoteJobManager interface Kernel->API, re #11123 --- Code/Mantid/Framework/API/CMakeLists.txt | 1 + Code/Mantid/Framework/Kernel/CMakeLists.txt | 1 - .../inc/MantidKernel/IRemoteJobManager.h | 276 ------------------ 3 files changed, 1 insertion(+), 277 deletions(-) delete mode 100644 Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index f87f4cede245..97f66fde0547 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -220,6 +220,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/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt index 6f70ef56c341..887bba027157 100644 --- a/Code/Mantid/Framework/Kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt @@ -165,7 +165,6 @@ set ( INC_FILES inc/MantidKernel/InstrumentInfo.h inc/MantidKernel/InternetHelper.h inc/MantidKernel/Interpolation.h - inc/MantidKernel/IRemoteJobManager.h inc/MantidKernel/LibraryManager.h inc/MantidKernel/LibraryWrapper.h inc/MantidKernel/ListValidator.h diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h deleted file mode 100644 index 359619a09de1..000000000000 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IRemoteJobManager.h +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H -#define MANTID_KERNEL_IREMOTEJOBMANAGER_H - -#include "MantidKernel/DllConfig.h" - -namespace Mantid { -namespace Kernel { -/** -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_KERNEL_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 - std::string submitDate; - /// Date-time the job actually started running. No particular - /// format can be assumed - std::string startDate; - /// Date-time the job finished. No particular format can be - /// assumed - std::string 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(std::string &username, 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 Kernel -} // namespace Mantid - -#endif // MANTID_KERNEL_IREMOTEJOBMANAGER_H From a905bd1afa82313890c28efe03ddc9504c38d6cd Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Sat, 21 Mar 2015 12:42:48 +0000 Subject: [PATCH 10/37] and update namespace, re #11123 --- .../Framework/API/inc/MantidAPI/IRemoteJobManager.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h index 8ee6dd776735..096289b52882 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -1,10 +1,10 @@ #ifndef MANTID_KERNEL_IREMOTEJOBMANAGER_H #define MANTID_KERNEL_IREMOTEJOBMANAGER_H -#include "MantidKernel/DllConfig.h" +#include "MantidAPI/DllConfig.h" namespace Mantid { -namespace Kernel { +namespace API { /** Common interface to different remote job managers (job schedulers, web services, etc. such as MOAB, Platform LSF, or SLURM). @@ -63,7 +63,7 @@ along with this program. If not, see . File change history is stored at: . Code Documentation is available at: */ -class MANTID_KERNEL_DLL IRemoteJobManager { +class MANTID_API_DLL IRemoteJobManager { public: virtual ~IRemoteJobManager(){}; @@ -271,7 +271,7 @@ class MANTID_KERNEL_DLL IRemoteJobManager { // shared pointer type for the IRemoteJobManager typedef boost::shared_ptr IRemoteJobManager_sptr; -} // namespace Kernel +} // namespace API } // namespace Mantid #endif // MANTID_KERNEL_IREMOTEJOBMANAGER_H From 5505aacebfb1d65ed4ade82c8a74fb86e3a28f80 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 09:57:14 +0000 Subject: [PATCH 11/37] Added refactored cylinder algorithm Refs #11413 --- .../IndirectCylinderAbsorption.py | 191 ++++++++++++------ 1 file changed, 134 insertions(+), 57 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index d22e65e04404..d476d6677e3f 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.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, WorkspaceGroupProperty, PropertyMode +from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator, IntBoundedValidator class IndirectCylinderAbsorption(DataProcessorAlgorithm): @@ -14,27 +14,49 @@ 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.0, + 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.0, + 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.') @@ -42,81 +64,105 @@ def PyExec(self): from IndirectCommon import getEfixed, addSampleLogs 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) - - 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') 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: + 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: + 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_filename': self._sample_ws_name, 'sample_radius': self._sample_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)) + if self._can_ws_name is not None: + AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + if self._use_can_corrections: + addSampleLogs(self._acc_ws, sample_logs) + AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) + AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness', LogType='String', LogText=str(can_thickness)) 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 +170,52 @@ 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 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 From 00eaa1075b6843ac446492fe01cf4bce1765c436 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 10:12:48 +0000 Subject: [PATCH 12/37] Re add progress reporting, use AddSampleLogMultiple Refs #11413 --- .../IndirectCylinderAbsorption.py | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index d476d6677e3f..80b91f1fefe5 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -1,5 +1,5 @@ from mantid.simpleapi import * -from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceGroupProperty, PropertyMode +from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, WorkspaceGroupProperty, PropertyMode, Progress from mantid.kernel import StringMandatoryValidator, Direction, logger, FloatBoundedValidator, IntBoundedValidator @@ -22,7 +22,7 @@ def PyInit(self): self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, validator=FloatBoundedValidator(0.0), doc='Sample number density') - self.declareProperty(name='SampleRadius', defaultValue=0.0, + self.declareProperty(name='SampleRadius', defaultValue=0.1, validator=FloatBoundedValidator(0.0), doc='Sample radius') @@ -37,7 +37,7 @@ def PyInit(self): self.declareProperty(name='CanNumberDensity', defaultValue=0.1, validator=FloatBoundedValidator(0.0), doc='Can number density') - self.declareProperty(name='CanRadius', defaultValue=0.0, + self.declareProperty(name='CanRadius', defaultValue=0.2, validator=FloatBoundedValidator(0.0), doc='Can radius') self.declareProperty(name='CanScaleFactor', defaultValue=1.0, @@ -61,9 +61,16 @@ def PyInit(self): def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() + + # Set up progress reporting + 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) + efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' @@ -72,6 +79,7 @@ def PyExec(self): SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) + prog.report('Calculating sample corrections') CylinderAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleNumberDensity=self._sample_number_density, @@ -97,6 +105,8 @@ def PyExec(self): 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) @@ -117,6 +127,8 @@ def PyExec(self): 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) @@ -130,21 +142,26 @@ def PyExec(self): Target='DeltaE', EMode='Indirect', EFixed=efixed) DeleteWorkspace(sample_wave_ws) - sample_logs = {'sample_shape': 'cylinder', - 'sample_filename': self._sample_ws_name, - 'sample_radius': self._sample_radius} - addSampleLogs(self._ass_ws, sample_logs) - addSampleLogs(self._output_ws, sample_logs) + # Record sample logs + prog.report('Recording 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: - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: - addSampleLogs(self._acc_ws, sample_logs) - AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + sample_log_workspaces.append(self._acc_ws) AddSampleLog(Workspace=self._output_ws, LogName='can_thickness', LogType='String', LogText=str(can_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 Abs group workspace if it is wanted, delete if not @@ -184,9 +201,10 @@ def _setup(self): 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._events = self.getPropertyValue('Events') self._plot = self.getProperty('Plot').value + self._output_ws = self.getPropertyValue('OutputWorkspace') self._abs_ws = self.getPropertyValue('CorrectionsWorkspace') From da492d87116b2e22593440252b884b1c76f0c40d Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 10:45:09 +0000 Subject: [PATCH 13/37] Updated unit test and docs for cylinder algo Refs #11413 --- .../IndirectCylinderAbsorptionTest.py | 66 +++++++++++----- .../IndirectCylinderAbsorption-v1.rst | 77 +++++++++++++++---- 2 files changed, 107 insertions(+), 36 deletions(-) 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/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst index eb7c25150ad5..c076e74c6959 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:: SampleCorrectionsWithCanCorrections + + 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:: SampleCorrectionsWithCanCorrections + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + DeleteWorkspace(fact) + +**Output:** + +.. testoutput:: SampleCorrectionsWithCanCorrections + + Corrected workspace is intensity against Energy transfer + Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength .. categories:: From 18b2570612c36d11f4c5c1504ed2894d8d7ce451 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 11:03:55 +0000 Subject: [PATCH 14/37] Added refactored flat plate algorithm Refs #11413 --- .../IndirectCylinderAbsorption.py | 18 ++ .../IndirectFlatPlateAbsorption.py | 222 +++++++++++++----- 2 files changed, 181 insertions(+), 59 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index 80b91f1fefe5..6581e6327b26 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -5,6 +5,24 @@ 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" diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py index 0fb3e2c3fe04..c8662f3760a3 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,31 +35,61 @@ 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 @@ -46,84 +97,114 @@ def PyExec(self): 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') + prog.report('Recording samle 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, + 'sample_thickness': self._sample_thickness, '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)) + if self._can_ws_name is not None: + AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + if self._use_can_corrections: + addSampleLogs(self._acc_ws, sample_logs) + AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) + AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness1', LogType='String', LogText=str(self._can_front_thickness)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness2', LogType='String', LogText=str(self._can_back_thickness)) 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 +213,46 @@ 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() + + # TODO - self._can_ws = self.getPropertyValue('CanWorkspace') - if self._can_ws == '': - self._can_ws = None + return issues # Register algorithm with Mantid From 5f5fb2537d4a7b05585f966f419e25eb44981d74 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 11:11:20 +0000 Subject: [PATCH 15/37] More refactoring of algorithms Refs #11413 --- .../IndirectCylinderAbsorption.py | 6 +-- .../IndirectFlatPlateAbsorption.py | 41 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index 6581e6327b26..5c9b162d1744 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -161,7 +161,7 @@ def PyExec(self): DeleteWorkspace(sample_wave_ws) # Record sample logs - prog.report('Recording 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), @@ -172,7 +172,7 @@ def PyExec(self): sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness', LogType='String', LogText=str(can_thickness)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness', LogType='Number', LogText=str(can_thickness)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] @@ -236,7 +236,7 @@ def _setup(self): def validateInputs(self): """ - Validate options + Validate algorithm options. """ self._setup() diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py index c8662f3760a3..0ecfb7ef159a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py @@ -92,7 +92,7 @@ def PyInit(self): def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() @@ -169,24 +169,27 @@ def PyExec(self): DeleteWorkspace(sample_wave_ws) prog.report('Recording samle 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_thickness, - 'element_size': self._element_size} - addSampleLogs(self._ass_ws, sample_logs) - addSampleLogs(self._output_ws, sample_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: - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: - addSampleLogs(self._acc_ws, sample_logs) - AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness1', LogType='String', LogText=str(self._can_front_thickness)) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness2', LogType='String', LogText=str(self._can_back_thickness)) + sample_log_workspaces.append(self._acc_ws) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness_1', LogType='Number', LogText=str(self._can_front_thickness)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness_2', LogType='Number', LogText=str(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) @@ -250,7 +253,11 @@ def validateInputs(self): self._setup() issues = dict() - # TODO + 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' return issues From 0138c997b3632c6c971477e35613e3c75c6052b8 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 11:27:42 +0000 Subject: [PATCH 16/37] Update unit and doc tests for flat plate algo Refs #11413 --- .../IndirectFlatPlateAbsorptionTest.py | 75 ++++++++++------- .../IndirectFlatPlateAbsorption-v1.rst | 80 +++++++++++++++---- 2 files changed, 108 insertions(+), 47 deletions(-) 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/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst index 0557ecb326b9..c3a46505dc30 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,80 @@ 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 + Ass workspace is Attenuation factor against Wavelength + +**Example - Sample and container corrections for IRIS:** + +.. testcode:: SampleCorrectionsWithCanSubtraction + + 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:: SampleCorrectionsWithCanSubtraction + + DeleteWorkspace(red_ws) + DeleteWorkspace(can_ws) + DeleteWorkspace(corrected) + 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 .. categories:: From 57de1c5117efb4ad708bdafca55883677a15f219 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 11:52:20 +0000 Subject: [PATCH 17/37] Fix failing doc test Refs #11413 --- .../docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst index c3a46505dc30..1197c203db28 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst @@ -104,5 +104,6 @@ Usage Corrected workspace is intensity against Energy transfer Ass workspace is Attenuation factor against Wavelength + Acc workspace is Attenuation factor against Wavelength .. categories:: From 309c17c0dcd987fee2083c4811ae89404d85c5b7 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 16:30:36 +0000 Subject: [PATCH 18/37] Added refactored annulus algorithm Refs #11413 --- .../IndirectAnnulusAbsorption.py | 229 +++++++++++++----- 1 file changed, 171 insertions(+), 58 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py index ce5d2aa46a29..0b4cc309378a 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,31 +14,57 @@ 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.') @@ -48,12 +74,11 @@ def PyExec(self): 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,44 +86,96 @@ 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_thickness1 = self._sample_inner_radius - self._can_inner_radius + can_thickness2 = self._can_outer_radius - self._sample_outer_radius + logger.information('Can thickness: ' + str(can_thickness1) + ' & ' + str(can_thickness2)) + + 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_thickness1, + 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_thickness2, + 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') + prog.report('Recording sample logs') sample_logs = {'sample_shape': 'annulus', 'sample_filename': self._sample_ws_name, 'sample_inner': self._sample_inner_radius, @@ -108,24 +185,33 @@ def PyExec(self): 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)) + if self._can_ws_name is not None: + AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + if self._use_can_corrections: + addSampleLogs(self._acc_ws, sample_logs) + AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) + AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness1', LogType='String', LogText=str(can_thickness1)) + AddSampleLog(Workspace=self._output_ws, LogName='can_thickness2', LogType='String', LogText=str(can_thickness2)) 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 +220,51 @@ 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() + + # TODO: geometry validation + + 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 From 89ebec882b5fe1b61a0bea2ce13cda511c376279 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 16:39:20 +0000 Subject: [PATCH 19/37] More refactoring, use AddSampleLOgMultiple Refs #11413 --- .../IndirectAnnulusAbsorption.py | 47 ++++++++++--------- .../IndirectCylinderAbsorption.py | 2 +- .../IndirectFlatPlateAbsorption.py | 4 +- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py index 0b4cc309378a..909cdd5c5a91 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py @@ -69,7 +69,7 @@ def PyInit(self): def PyExec(self): - from IndirectCommon import getEfixed, addSampleLogs + from IndirectCommon import getEfixed self._setup() @@ -114,9 +114,9 @@ def PyExec(self): 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_thickness1 = self._sample_inner_radius - self._can_inner_radius - can_thickness2 = self._can_outer_radius - self._sample_outer_radius - logger.information('Can thickness: ' + str(can_thickness1) + ' & ' + str(can_thickness2)) + 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') @@ -126,7 +126,7 @@ def PyExec(self): AnnularRingAbsorption(InputWorkspace=can1_wave_ws, OutputWorkspace='__Acc1', SampleHeight=3.0, - SampleThickness=can_thickness1, + SampleThickness=can_thickness_1, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._sample_outer_radius, SampleChemicalFormula=self._can_chemical_formula, @@ -138,7 +138,7 @@ def PyExec(self): AnnularRingAbsorption(InputWorkspace=can2_wave_ws, OutputWorkspace='__Acc2', SampleHeight=3.0, - SampleThickness=can_thickness2, + SampleThickness=can_thickness_2, CanInnerRadius=self._sample_inner_radius, CanOuterRadius=self._can_outer_radius, SampleChemicalFormula=self._can_chemical_formula, @@ -149,6 +149,7 @@ def PyExec(self): 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) @@ -176,24 +177,27 @@ def PyExec(self): DeleteWorkspace(sample_wave_ws) prog.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) + 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: - AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) + sample_logs.append(('can_filename', self._can_ws_name)) + sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: - addSampleLogs(self._acc_ws, sample_logs) - AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name)) - AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale)) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness1', LogType='String', LogText=str(can_thickness1)) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness2', LogType='String', LogText=str(can_thickness2)) + 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) @@ -257,6 +261,7 @@ def validateInputs(self): issues = dict() # TODO: geometry validation + # can inner < sample inner < sample outer < can outer if self._use_can_corrections and self._can_chemical_formula == '': issues['CanChemicalFormula'] = 'Must be set to use can corrections' diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py index 5c9b162d1744..c413199a8992 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py @@ -172,7 +172,7 @@ def PyExec(self): sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness', LogType='Number', LogText=str(can_thickness)) + 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] diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py index 0ecfb7ef159a..4651084b326a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py @@ -182,8 +182,8 @@ def PyExec(self): sample_logs.append(('can_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness_1', LogType='Number', LogText=str(self._can_front_thickness)) - AddSampleLog(Workspace=self._output_ws, LogName='can_thickness_2', LogType='Number', LogText=str(self._can_back_thickness)) + 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] From 773f9823690e471fcbe8fdef107c811c751bb73f Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 16:45:16 +0000 Subject: [PATCH 20/37] Remove function from IndirectCommon Refs #11422 --- .../scripts/Inelastic/IndirectCommon.py | 20 ------------------- 1 file changed, 20 deletions(-) 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)) From 3041060622c3a203c1cbe81af61a16611b97fcd6 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 16:50:37 +0000 Subject: [PATCH 21/37] Remove most instances THose remaining will be fixed in another ticket Refs #11422 --- Code/Mantid/scripts/Inelastic/IndirectAbsCor.py | 11 +++++++---- .../scripts/Inelastic/IndirectDataAnalysis.py | 12 ++++++++---- Code/Mantid/scripts/test/IndirectCommonTests.py | 17 ----------------- 3 files changed, 15 insertions(+), 25 deletions(-) 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/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index 54e34ca44457..b3f7d2945f95 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -200,8 +200,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 +272,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 #----------------------------------------------------------- From 04a7e7e9ec68200ee9b78977a685ff15b2c9378d Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 23 Mar 2015 16:54:21 +0000 Subject: [PATCH 22/37] Remove StartTime and EndTime calls from algorithms Refs #11422 --- .../PythonInterface/plugins/algorithms/Symmetrise.py | 5 ----- .../WorkflowAlgorithms/InelasticIndirectReduction.py | 5 ----- .../algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py | 5 ----- 3 files changed, 15 deletions(-) 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/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) From 2cff93e9e257b2079d5af9c8daace095413bbf24 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Tue, 24 Mar 2015 09:02:14 +0000 Subject: [PATCH 23/37] Update annulus unit test for algorithm changes Refs #11413 --- .../IndirectAnnulusAbsorptionTest.py | 82 +++++++++++-------- 1 file changed, 48 insertions(+), 34 deletions(-) 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__': From 5533feb3c43c5a7720f34131551ba6a7d87f7536 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Tue, 24 Mar 2015 09:26:42 +0000 Subject: [PATCH 24/37] Updated documentation Refs #11413 --- .../IndirectAnnulusAbsorption-v1.rst | 82 +++++++++++++++---- .../IndirectCylinderAbsorption-v1.rst | 6 +- .../IndirectFlatPlateAbsorption-v1.rst | 6 +- 3 files changed, 70 insertions(+), 24 deletions(-) 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 c076e74c6959..ef2b38b70409 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst @@ -61,7 +61,7 @@ Usage **Example - Sample and container corrections for IRIS:** -.. testcode:: SampleCorrectionsWithCanCorrections +.. testcode:: SampleAndCanCorrections red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') @@ -88,7 +88,7 @@ Usage print ('Acc workspace is %s against %s' % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) -.. testcleanup:: SampleCorrectionsWithCanCorrections +.. testcleanup:: SampleAndCanCorrections DeleteWorkspace(red_ws) DeleteWorkspace(can_ws) @@ -97,7 +97,7 @@ Usage **Output:** -.. testoutput:: SampleCorrectionsWithCanCorrections +.. testoutput:: SampleAndCanCorrections Corrected workspace is intensity against Energy transfer Ass workspace is Attenuation factor against Wavelength diff --git a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst index 1197c203db28..7e83f5ec675d 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst @@ -63,7 +63,7 @@ Usage **Example - Sample and container corrections for IRIS:** -.. testcode:: SampleCorrectionsWithCanSubtraction +.. testcode:: SampleAndCanCorrections red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs') can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs') @@ -91,7 +91,7 @@ Usage print ('Acc workspace is %s against %s' % (acc.YUnitLabel(), acc.getAxis(0).getUnit().caption())) -.. testcleanup:: SampleCorrectionsWithCanSubtraction +.. testcleanup:: SampleAndCanCorrections DeleteWorkspace(red_ws) DeleteWorkspace(can_ws) @@ -100,7 +100,7 @@ Usage **Output:** -.. testoutput:: SampleCorrectionsWithCanSubtraction +.. testoutput:: SampleAndCanCorrections Corrected workspace is intensity against Energy transfer Ass workspace is Attenuation factor against Wavelength From ceddee39c59a5b7b27d7e604787ba87c7aa85a38 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Tue, 24 Mar 2015 09:35:21 +0000 Subject: [PATCH 25/37] Validate geometry and fix bug with plot Refs #11413 --- .../IndirectAnnulusAbsorption.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py index 909cdd5c5a91..3d9a00cb0c2a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py @@ -214,7 +214,7 @@ def PyExec(self): from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() mantid_plot.plotSpectrum(plot_data, 0) - if self._abs_ws == '': + if self._abs_ws != '': mantid_plot.plotSpectrum(plot_corr, 0) @@ -260,15 +260,22 @@ def validateInputs(self): self._setup() issues = dict() - # TODO: geometry validation - # can inner < sample inner < sample outer < can outer - 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' + return issues From f9c905e9c126e2885cc96fba7c7604f9dd010f81 Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Tue, 24 Mar 2015 14:36:14 +0000 Subject: [PATCH 26/37] use DateAndTime in job info struct, re #11123 --- .../Framework/API/inc/MantidAPI/IRemoteJobManager.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h index 096289b52882..9f650c503545 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -2,6 +2,7 @@ #define MANTID_KERNEL_IREMOTEJOBMANAGER_H #include "MantidAPI/DllConfig.h" +#include "MantidKernel/DateAndTime.h" namespace Mantid { namespace API { @@ -89,13 +90,14 @@ class MANTID_API_DLL IRemoteJobManager { /// ID of the transaction where this job is included std::string transactionID; /// Date-time of submission. No particular format can be assumed - std::string submitDate; + /// from the specific remote job managers + Mantid::Kernel::DateAndTime submitDate; /// Date-time the job actually started running. No particular /// format can be assumed - std::string startDate; + Mantid::Kernel::DateAndTime startDate; /// Date-time the job finished. No particular format can be /// assumed - std::string completionTime; + Mantid::Kernel::DateAndTime completionTime; }; /** From 9b111262379ee6d7a4899b3a0fe7d4190a4addbe Mon Sep 17 00:00:00 2001 From: Federico Montesino Pouzols Date: Tue, 24 Mar 2015 14:39:49 +0000 Subject: [PATCH 27/37] fix comments, re #11123 --- Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h index 9f650c503545..2035e271f89e 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -90,7 +90,8 @@ class MANTID_API_DLL IRemoteJobManager { /// 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 + /// 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 @@ -276,4 +277,4 @@ typedef boost::shared_ptr IRemoteJobManager_sptr; } // namespace API } // namespace Mantid -#endif // MANTID_KERNEL_IREMOTEJOBMANAGER_H +#endif // MANTID_API_IREMOTEJOBMANAGER_H From 6a4a96735b4bd5faf05c5e77d27a02b6e72704d5 Mon Sep 17 00:00:00 2001 From: Vickie Lynch Date: Tue, 24 Mar 2015 16:10:00 -0400 Subject: [PATCH 28/37] Refs #11244 fix xml output file --- .../Framework/Crystal/src/SCDCalibratePanels.cpp | 2 +- .../source/algorithms/IntegrateEllipsoids-v1.rst | 2 +- .../docs/source/algorithms/IntegratePeaksMD-v2.rst | 2 +- .../source/algorithms/SCDCalibratePanels-v1.rst | 13 +++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) 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/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:: From ed7ed7a7cf326809816e16040fdca0c9b695a20f Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Wed, 25 Mar 2015 14:05:40 +0000 Subject: [PATCH 29/37] Use AddSampleLogMultiple in ConvFit Refs #11426 --- .../scripts/Inelastic/IndirectDataAnalysis.py | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index 54e34ca44457..9a66123552e0 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") From 9f3b6e1a4d663d478e9eb0420c666e45add3e55d Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 26 Mar 2015 10:34:34 +0000 Subject: [PATCH 30/37] Re #11428 Use mantid help system --- .../CustomInterfaces/src/Muon/ALCBaselineModellingView.cpp | 6 ++---- .../CustomInterfaces/src/Muon/ALCDataLoadingView.cpp | 7 +++---- .../CustomInterfaces/src/Muon/ALCPeakFittingView.cpp | 7 +++---- 3 files changed, 8 insertions(+), 12 deletions(-) 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 From 183833545ec2d20822baa799abac61c9be9f4a3c Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 26 Mar 2015 10:44:03 +0000 Subject: [PATCH 31/37] Re #11428 Add ALC documentation --- .../docs/source/interfaces/Muon_ALC.rst | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Code/Mantid/docs/source/interfaces/Muon_ALC.rst 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 From 80121f8699bf2cccb99db9fb18ccb89fe6b9ebf3 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 26 Mar 2015 11:52:49 +0000 Subject: [PATCH 32/37] Re #11086 Enable and update non-zero field unit tests --- .../CurveFitting/test/DynamicKuboToyabeTest.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index 74e8717d9fb9..c3a78ecebf90 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -79,7 +79,7 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_DELTA( y[4], 0.323394, 0.000001); } - void xtestZNDKTFunction() + void testZNDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) for non-zero Field and Zero Nu (ZN) const double asym = 1.0; @@ -107,7 +107,7 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_DELTA( y[4], 0.055052, 0.000001); } - void xtestDKTFunction() + void testDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) (non-zero Field, non-zero Nu) const double asym = 1.0; @@ -129,10 +129,10 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); - TS_ASSERT_DELTA( y[1], 0.822498, 0.000001); - TS_ASSERT_DELTA( y[2], 0.518536, 0.000001); - TS_ASSERT_DELTA( y[3], 0.295988, 0.000001); - TS_ASSERT_DELTA( y[4], 0.175489, 0.000001); + TS_ASSERT_DELTA( y[1], 0.821663, 0.000001); + TS_ASSERT_DELTA( y[2], 0.518974, 0.000001); + TS_ASSERT_DELTA( y[3], 0.297548, 0.000001); + TS_ASSERT_DELTA( y[4], 0.177036, 0.000001); } From 833a1049ada84941a9ebbf79f91e4c4fd370ec72 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 26 Mar 2015 12:00:15 +0000 Subject: [PATCH 33/37] Re #11086 Move integration parameters to function --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 32599d08835e..52a6cbc611ac 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -6,10 +6,6 @@ #include "MantidAPI/FunctionFactory.h" #include -#define JMAX 14 -#define JMAXP (JMAX+1) -#define K 5 - namespace Mantid { namespace CurveFitting @@ -102,9 +98,14 @@ void polint (double xa[], double ya[], int n, double x, double& y, double& dy) { // Integration double integral (double func(const double, const double, const double), - const double a, const double b, const double g, const double w0) { - int j; - double ss,dss; + const double a, const double b, const double g, const double w0) { + + const int JMAX = 14; + const int JMAXP = JMAX + 1; + const int K = 5; + + int j; + double ss,dss; double h[JMAXP+1], s[JMAXP]; h[1] = 1.0; From 944f61b3386704965d915723db4a55bcc08e4f5c Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Thu, 26 Mar 2015 12:01:21 +0000 Subject: [PATCH 34/37] Refs #11411 Remove hack from FindJsonCPP.cmake --- Code/Mantid/Build/CMake/FindJsonCPP.cmake | 5 ----- 1 file changed, 5 deletions(-) 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 ) From 1c2bfb9cd271e9a91c1ee625f9cf8bd2d3318462 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 26 Mar 2015 12:08:09 +0000 Subject: [PATCH 35/37] Re #11086 Replace error messages with exceptions --- Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 52a6cbc611ac..d19e1e94fada 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -83,8 +83,7 @@ void polint (double xa[], double ya[], int n, double x, double& y, double& dy) { hp=xa[i+m]-x; w=c[i+1]-d[i]; if((den=ho-hp)==0.0){ //error message!!! - std::cout << "Error in routine polint\n" << std::endl; - exit(1); + throw std::runtime_error("Error in routin polint"); } den=w/den; d[i]=hp*den; @@ -117,7 +116,7 @@ double integral (double func(const double, const double, const double), } h[j+1]=h[j]/9.0; } - std::cout << "integrate(): Too many steps in routine integrate\n" << std::endl; + throw std::runtime_error("Too many steps in routine integrate"); return 0.0; } From 23b9dd22ff17d9d2c60fa6da9a680518a6b62833 Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 26 Mar 2015 21:19:07 +0100 Subject: [PATCH 36/37] Refs #11174. Added failing test case and fix problem. --- .../CurveFitting/test/FunctionParameterDecoratorFitTest.h | 2 +- .../Framework/TestHelpers/src/WorkspaceCreationHelper.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h index 47cc259f3558..9539e6aebaa6 100644 --- a/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h @@ -70,7 +70,7 @@ class FunctionParameterDecoratorFitTest : public CxxTest::TestSuite { void testFit() { Workspace2D_sptr ws = - WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 1.5); + WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 0.5); FunctionParameterDecorator_sptr fn = boost::make_shared(); diff --git a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index 11df5295a6c6..addcd3b92126 100644 --- a/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -84,7 +84,7 @@ Workspace2D_sptr Create1DWorkspaceConstant(int size, double value, 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); + std::fill(e1.access().begin(), e1.access().end(), error); Workspace2D_sptr retVal(new Workspace2D); retVal->initialize(1, size, size); retVal->setX(0, x1); From 5b7b69a216d4efdda4e07f85e5a22301a3ed1205 Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 26 Mar 2015 22:41:56 +0100 Subject: [PATCH 37/37] Refs #11174. Adding small tolerance to test PolarizationCorrectionTest failed, because the error on the output workspace of the algorithm is 2.2e-16 instead of 0.0. I could not find out why, so I added a small tolerance to the unit test. --- .../Framework/Algorithms/test/PolarizationCorrectionTest.h | 1 + .../Framework/TestHelpers/src/WorkspaceCreationHelper.cpp | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) 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/TestHelpers/src/WorkspaceCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index addcd3b92126..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(e1.access().begin(), e1.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);