Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
mantidproject
mantid
Commits
2fae76f2
Commit
2fae76f2
authored
Mar 31, 2016
by
Roman Tolchenov
Browse files
Re #15699. TableWorkspace clones selected columns.
parent
041fa9f8
Changes
13
Hide whitespace changes
Inline
Side-by-side
Framework/API/inc/MantidAPI/IFunctionGeneral.h
View file @
2fae76f2
...
...
@@ -3,8 +3,8 @@
#include
"MantidAPI/DllConfig.h"
#include
"MantidAPI/IFunction.h"
#include
"MantidAPI/FunctionDomainGeneral.h"
#include
"MantidAPI/IFunction.h"
#include
"MantidKernel/Logger.h"
namespace
Mantid
{
...
...
@@ -17,7 +17,7 @@ namespace API {
The domain and the values object can have different sizes.
In particular the domain can be empty.
Copyright © 2016 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
National Laboratory & European Spallation Source
...
...
@@ -51,7 +51,7 @@ public:
/// Provide a concrete function in an implementation that operates on a
/// FunctionDomainGeneral.
virtual
void
functionGeneral
(
const
FunctionDomainGeneral
&
domain
,
FunctionValues
&
values
)
const
=
0
;
FunctionValues
&
values
)
const
=
0
;
/// Get number of columns that the domain must have.
/// If consider the collection of these columns as a table
...
...
@@ -61,11 +61,12 @@ public:
/// Get number of values per argument in the domain.
virtual
size_t
getNumberValuesPerArgument
()
const
=
0
;
/// Get the default size of an output FunctionValues object.
/// It is a number of values the function will produce if it is
/// given an empty domain.
/// Get the default size of a domain.
/// If a function is given an empty domain then it must output
/// a values object of the size:
/// getDefaultDomainSize() * getNumberValuesPerArgument()
/// The default size must not be infinite (max of size_t).
virtual
size_t
getDefault
Values
Size
()
const
;
virtual
size_t
getDefault
Domain
Size
()
const
;
protected:
static
Kernel
::
Logger
g_log
;
...
...
Framework/API/inc/MantidAPI/ITableWorkspace.h
View file @
2fae76f2
...
...
@@ -122,7 +122,8 @@ public:
ITableWorkspace
()
{}
/// Returns a clone of the workspace
ITableWorkspace_uptr
clone
()
const
{
return
ITableWorkspace_uptr
(
doClone
());
}
ITableWorkspace_uptr
clone
(
const
std
::
vector
<
std
::
string
>
&
colNames
=
std
::
vector
<
std
::
string
>
())
const
;
ITableWorkspace
&
operator
=
(
const
ITableWorkspace
&
)
=
delete
;
/// Return the workspace typeID
...
...
@@ -328,7 +329,8 @@ protected:
void
removeFromColumn
(
Column
*
c
,
size_t
index
)
{
c
->
remove
(
index
);
}
private:
ITableWorkspace
*
doClone
()
const
override
=
0
;
ITableWorkspace
*
doClone
()
const
override
{
return
doCloneColumns
(
std
::
vector
<
std
::
string
>
());}
virtual
ITableWorkspace
*
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
=
0
;
};
// =====================================================================================
...
...
Framework/API/src/IFunctionGeneral.cpp
View file @
2fae76f2
...
...
@@ -26,12 +26,12 @@ void IFunctionGeneral::functionDeriv(const FunctionDomain &domain,
size_t
IFunctionGeneral
::
getValuesSize
(
const
FunctionDomain
&
domain
)
const
{
if
(
domain
.
size
()
==
0
||
getNumberDomainColumns
()
==
0
)
{
return
getDefault
Values
Size
()
*
getNumberValuesPerArgument
();
return
getDefault
Domain
Size
()
*
getNumberValuesPerArgument
();
}
return
domain
.
size
()
*
getNumberValuesPerArgument
();
}
size_t
IFunctionGeneral
::
getDefault
Values
Size
()
const
{
return
0
;
}
size_t
IFunctionGeneral
::
getDefault
Domain
Size
()
const
{
return
0
;
}
}
// namespace API
}
// namespace Mantid
Framework/API/src/ITableWorkspace.cpp
View file @
2fae76f2
...
...
@@ -5,8 +5,14 @@
namespace
Mantid
{
namespace
API
{
/**
*/
/// Returns a clone of the workspace
/// @param colNames :: Names of the column to clone. If empty clone
/// all columns.
ITableWorkspace_uptr
ITableWorkspace
::
clone
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
{
return
ITableWorkspace_uptr
(
doCloneColumns
(
colNames
));
}
const
std
::
string
ITableWorkspace
::
toString
()
const
{
std
::
ostringstream
os
;
os
<<
id
()
<<
"
\n
"
;
...
...
Framework/CurveFitting/inc/MantidCurveFitting/GeneralDomainCreator.h
View file @
2fae76f2
...
...
@@ -10,6 +10,7 @@ namespace Mantid {
namespace
API
{
class
IFunctionGeneral
;
class
Column
;
class
ITableWorkspace
;
}
namespace
CurveFitting
{
...
...
@@ -61,6 +62,8 @@ public:
void
declareDatasetProperties
(
const
std
::
string
&
suffix
=
""
,
bool
addProp
=
true
)
override
;
private:
/// Retrive the input workspace from the property manager.
boost
::
shared_ptr
<
API
::
ITableWorkspace
>
getInputWorkspace
();
// Names of additional properties
/// Property names for columns in a TableWorkspace to be passed to
/// the domain.
...
...
Framework/CurveFitting/src/GeneralDomainCreator.cpp
View file @
2fae76f2
#include
"MantidCurveFitting/GeneralDomainCreator.h"
#include
"MantidAPI/FunctionDomainGeneral.h"
#include
"MantidAPI/IFunctionGeneral.h"
#include
"MantidAPI/ITableWorkspace.h"
#include
"MantidAPI/Workspace.h"
#include
"MantidAPI/ITableWorkspace.h"
#include
"MantidAPI/WorkspaceProperty.h"
#include
"MantidAPI/WorkspaceFactory.h"
#include
"MantidAPI/WorkspaceProperty.h"
#include
"MantidCurveFitting/GeneralDomainCreator.h"
#include
"MantidKernel/PropertyWithValue.h"
#include
<boost/lexical_cast.hpp>
...
...
@@ -27,12 +28,12 @@ GeneralDomainCreator::GeneralDomainCreator(
:
IDomainCreator
(
&
manager
,
std
::
vector
<
std
::
string
>
(
1
,
workspacePropertyName
))
{
m_defaultValuesSize
=
fun
.
getDefault
Values
Size
();
m_defaultValuesSize
=
fun
.
getDefault
Domain
Size
();
auto
nDomainColumns
=
fun
.
getNumberDomainColumns
();
if
(
nDomainColumns
>
0
)
{
m_domainColumnNames
.
push_back
(
"ArgumentColumn"
);
for
(
size_t
i
=
1
;
i
<
nDomainColumns
;
++
i
)
{
for
(
size_t
i
=
1
;
i
<
nDomainColumns
;
++
i
)
{
m_domainColumnNames
.
push_back
(
m_domainColumnNames
.
front
()
+
"_"
+
boost
::
lexical_cast
<
std
::
string
>
(
i
));
}
...
...
@@ -42,7 +43,7 @@ GeneralDomainCreator::GeneralDomainCreator(
if
(
nDataColumns
>
0
)
{
m_dataColumnNames
.
push_back
(
"DataColumn"
);
m_weightsColumnNames
.
push_back
(
"WeightsColumn"
);
for
(
size_t
i
=
1
;
i
<
nDataColumns
;
++
i
)
{
for
(
size_t
i
=
1
;
i
<
nDataColumns
;
++
i
)
{
auto
si
=
"_"
+
boost
::
lexical_cast
<
std
::
string
>
(
i
);
m_dataColumnNames
.
push_back
(
m_dataColumnNames
.
front
()
+
si
);
m_weightsColumnNames
.
push_back
(
m_weightsColumnNames
.
front
()
+
si
);
...
...
@@ -57,20 +58,32 @@ GeneralDomainCreator::GeneralDomainCreator(
/// other stuff if needed
void
GeneralDomainCreator
::
declareDatasetProperties
(
const
std
::
string
&
suffix
,
bool
addProp
)
{
for
(
auto
&
propName
:
m_domainColumnNames
)
{
for
(
auto
&
propName
:
m_domainColumnNames
)
{
declareProperty
(
new
Kernel
::
PropertyWithValue
<
std
::
string
>
(
propName
,
""
),
"A name of a domain column."
);
}
for
(
auto
&
propName
:
m_dataColumnNames
)
{
for
(
auto
&
propName
:
m_dataColumnNames
)
{
declareProperty
(
new
Kernel
::
PropertyWithValue
<
std
::
string
>
(
propName
,
""
),
"A name of a fitting data column."
);
}
for
(
auto
&
propName
:
m_weightsColumnNames
)
{
for
(
auto
&
propName
:
m_weightsColumnNames
)
{
declareProperty
(
new
Kernel
::
PropertyWithValue
<
std
::
string
>
(
propName
,
""
),
"A name of a fitting weights column."
);
}
}
/// Retrive the input workspace from the property manager.
boost
::
shared_ptr
<
API
::
ITableWorkspace
>
GeneralDomainCreator
::
getInputWorkspace
()
{
auto
workspacePropertyName
=
m_workspacePropertyNames
.
front
();
API
::
Workspace_sptr
ws
=
m_manager
->
getProperty
(
workspacePropertyName
);
auto
tableWorkspace
=
boost
::
dynamic_pointer_cast
<
API
::
ITableWorkspace
>
(
ws
);
if
(
!
tableWorkspace
)
{
throw
std
::
invalid_argument
(
"InputWorkspace must be a TableWorkspace."
);
}
return
tableWorkspace
;
}
/**
* Creates a domain corresponding to the assigned MatrixWorkspace
*
...
...
@@ -83,19 +96,14 @@ void GeneralDomainCreator::createDomain(
boost
::
shared_ptr
<
FunctionValues
>
&
values
,
size_t
i0
)
{
// get the workspace
auto
workspacePropertyName
=
m_workspacePropertyNames
.
front
();
API
::
Workspace_sptr
ws
=
m_manager
->
getProperty
(
workspacePropertyName
);
auto
tableWorkspace
=
boost
::
dynamic_pointer_cast
<
API
::
ITableWorkspace
>
(
ws
);
if
(
!
tableWorkspace
)
{
throw
std
::
invalid_argument
(
"InputWorkspace must be a TableWorkspace."
);
}
auto
tableWorkspace
=
getInputWorkspace
();
size_t
domainSize
=
0
;
domain
.
reset
(
new
FunctionDomainGeneral
);
// Create the domain
if
(
!
m_domainColumnNames
.
empty
())
{
auto
&
generalDomain
=
*
static_cast
<
FunctionDomainGeneral
*>
(
domain
.
get
());
for
(
auto
&
propName
:
m_domainColumnNames
)
{
auto
&
generalDomain
=
*
static_cast
<
FunctionDomainGeneral
*>
(
domain
.
get
());
for
(
auto
&
propName
:
m_domainColumnNames
)
{
std
::
string
columnName
=
m_manager
->
getPropertyValue
(
propName
);
auto
column
=
tableWorkspace
->
getColumn
(
columnName
);
generalDomain
.
addColumn
(
column
);
...
...
@@ -110,13 +118,14 @@ void GeneralDomainCreator::createDomain(
values
.
reset
(
new
FunctionValues
);
}
auto
nDataColumns
=
m_dataColumnNames
.
size
();
for
(
size_t
i
=
0
;
i
<
nDataColumns
;
++
i
)
{
// Append each column to values' fitting data
for
(
size_t
i
=
0
;
i
<
nDataColumns
;
++
i
)
{
std
::
string
columnName
=
m_manager
->
getPropertyValue
(
m_dataColumnNames
[
i
]);
auto
dataColumn
=
tableWorkspace
->
getColumn
(
columnName
);
columnName
=
m_manager
->
getPropertyValue
(
m_weightsColumnNames
[
i
]);
auto
weightsColumn
=
tableWorkspace
->
getColumn
(
columnName
);
values
->
expand
(
i0
+
domainSize
);
for
(
size_t
j
=
0
;
j
<
domainSize
;
++
j
)
{
for
(
size_t
j
=
0
;
j
<
domainSize
;
++
j
)
{
values
->
setFitData
(
i0
+
j
,
dataColumn
->
toDouble
(
j
));
values
->
setFitWeight
(
i0
+
j
,
weightsColumn
->
toDouble
(
j
));
}
...
...
@@ -141,10 +150,26 @@ Workspace_sptr GeneralDomainCreator::createOutputWorkspace(
boost
::
shared_ptr
<
FunctionDomain
>
domain
,
boost
::
shared_ptr
<
FunctionValues
>
values
,
const
std
::
string
&
outputWorkspacePropertyName
)
{
// don't need values, since the values need to be calculated spectrum by
// spectrum (see loop below).
UNUSED_ARG
(
values
);
return
Workspace_sptr
();
if
(
function
->
getValuesSize
(
*
domain
)
!=
values
->
size
())
{
throw
std
::
runtime_error
(
"Failed to create output workspace: domain and "
"values object don't match."
);
}
auto
inputWorkspace
=
getInputWorkspace
();
ITableWorkspace_sptr
outputWorkspace
=
WorkspaceFactory
::
Instance
().
createTable
();
size_t
rowCount
=
domain
->
size
();
if
(
rowCount
==
0
)
{
auto
&
generalFunction
=
dynamic_cast
<
IFunctionGeneral
&>
(
*
function
);
rowCount
=
generalFunction
.
getDefaultDomainSize
();
}
outputWorkspace
->
setRowCount
(
rowCount
);
auto
&
generalDomain
=
*
static_cast
<
FunctionDomainGeneral
*>
(
domain
.
get
());
for
(
size_t
col
=
0
;
col
<
generalDomain
.
columnCount
();
++
col
)
{
auto
column
=
generalDomain
.
getColumn
(
col
);
auto
outColumn
=
outputWorkspace
->
addColumn
(
column
->
type
(),
column
->
name
());
for
(
size_t
row
=
0
;
row
<
rowCount
;
++
row
)
{
}
}
return
outputWorkspace
;
}
/**
...
...
@@ -152,9 +177,7 @@ Workspace_sptr GeneralDomainCreator::createOutputWorkspace(
*
* @return Total domain size.
*/
size_t
GeneralDomainCreator
::
getDomainSize
()
const
{
return
0
;
}
size_t
GeneralDomainCreator
::
getDomainSize
()
const
{
return
0
;
}
}
// namespace CurveFitting
}
// namespace Mantid
Framework/CurveFitting/test/GeneralDomainCreatorTest.h
View file @
2fae76f2
...
...
@@ -55,10 +55,10 @@ public:
std
::
string
name
()
const
override
{
return
"TestFunction2"
;}
size_t
getNumberDomainColumns
()
const
override
{
return
0
;}
size_t
getNumberValuesPerArgument
()
const
override
{
return
2
;}
size_t
getDefault
Values
Size
()
const
override
{
return
5
;}
size_t
getDefault
Domain
Size
()
const
override
{
return
5
;}
void
functionGeneral
(
const
FunctionDomainGeneral
&
generalDomain
,
FunctionValues
&
values
)
const
override
{
double
a
=
getParameter
(
0
);
auto
n
=
getDefault
Values
Size
();
auto
n
=
getDefault
Domain
Size
();
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
values
.
setCalculated
(
i
,
a
*
double
(
i
));
values
.
setCalculated
(
i
+
n
,
a
*
(
10.0
-
double
(
i
)));
...
...
@@ -290,6 +290,11 @@ public:
TS_ASSERT_DELTA
(
fun
->
getParameter
(
0
),
1.0
,
1e-9
);
}
void
test_create_output
()
{
TableWorkspace_sptr
ws
=
makeData2
();
auto
copy
=
ws
->
clone
();
}
private:
TableWorkspace_sptr
makeData1
(
double
wgt3col
=
0.0
)
{
...
...
Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
View file @
2fae76f2
...
...
@@ -185,6 +185,7 @@ protected:
private:
PeaksWorkspace
*
doClone
()
const
override
{
return
new
PeaksWorkspace
(
*
this
);
}
ITableWorkspace
*
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
override
;
/// Initialize the table structure
void
initColumns
();
...
...
Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
View file @
2fae76f2
...
...
@@ -80,10 +80,7 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace {
public:
/// Constructor.
TableWorkspace
(
size_t
nrows
=
0
);
/// Returns a clone of the workspace
std
::
unique_ptr
<
TableWorkspace
>
clone
()
const
{
return
std
::
unique_ptr
<
TableWorkspace
>
(
doClone
());
}
TableWorkspace
&
operator
=
(
const
TableWorkspace
&
other
)
=
delete
;
/// Return the workspace typeID
const
std
::
string
id
()
const
override
{
return
"TableWorkspace"
;
}
...
...
@@ -296,7 +293,8 @@ protected:
TableWorkspace
(
const
TableWorkspace
&
other
);
private:
TableWorkspace
*
doClone
()
const
override
{
return
new
TableWorkspace
(
*
this
);
}
//TableWorkspace *doClone() const override { return new TableWorkspace(*this); }
ITableWorkspace
*
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
override
;
/// template method to find a given value in a table.
template
<
typename
Type
>
...
...
Framework/DataObjects/src/PeaksWorkspace.cpp
View file @
2fae76f2
...
...
@@ -842,6 +842,11 @@ API::LogManager_sptr PeaksWorkspace::logs() {
m_logCash
=
API
::
LogManager_sptr
(
&
(
this
->
mutableRun
()),
NullDeleter
());
return
m_logCash
;
}
ITableWorkspace
*
PeaksWorkspace
::
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
{
throw
Kernel
::
Exception
::
NotImplementedError
(
"PeaksWorkspace cannot clone columns."
);
}
}
}
...
...
Framework/DataObjects/src/TableWorkspace.cpp
View file @
2fae76f2
...
...
@@ -272,6 +272,26 @@ void TableWorkspace::sort(std::vector<std::pair<std::string, bool>> &criteria) {
}
}
/// Clone the workspace keeping only selected columns.
/// @param colNames :: Names of columns to clone.
API
::
ITableWorkspace
*
TableWorkspace
::
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
{
if
(
colNames
.
empty
())
{
return
new
TableWorkspace
(
*
this
);
}
auto
ws
=
new
TableWorkspace
();
ws
->
setRowCount
(
rowCount
());
auto
it
=
m_columns
.
cbegin
();
while
(
it
!=
m_columns
.
cend
())
{
if
(
colNames
.
end
()
!=
std
::
find
(
colNames
.
begin
(),
colNames
.
end
(),
(
**
it
).
name
()))
{
ws
->
addColumn
(
boost
::
shared_ptr
<
API
::
Column
>
((
*
it
)
->
clone
()));
}
++
it
;
}
// copy logs/properties.
ws
->
m_LogManager
=
boost
::
make_shared
<
API
::
LogManager
>
(
*
(
m_LogManager
));
return
ws
;
}
// template<>
// boost::tuples::null_type TableWorkspace::make_TupleRef<
// boost::tuples::null_type >(size_t j,const std::vector<std::string>&
...
...
Framework/DataObjects/test/TableWorkspaceTest.h
View file @
2fae76f2
...
...
@@ -305,7 +305,7 @@ public:
tw
.
getColumn
(
1
)
->
cell
<
std
::
string
>
(
0
)
=
"b"
;
tw
.
getColumn
(
2
)
->
cell
<
std
::
string
>
(
0
)
=
"c"
;
boost
::
scoped_ptr
<
TableWorkspace
>
cloned
(
tw
.
clone
().
release
());
boost
::
scoped_ptr
<
I
TableWorkspace
>
cloned
(
tw
.
clone
().
release
());
// Check clone is same as original.
TS_ASSERT_EQUALS
(
tw
.
columnCount
(),
cloned
->
columnCount
());
...
...
@@ -315,6 +315,27 @@ public:
TS_ASSERT_EQUALS
(
"c"
,
cloned
->
getColumn
(
2
)
->
cell
<
std
::
string
>
(
0
));
}
void
testCloneColumns
()
{
TableWorkspace
tw
(
1
);
tw
.
addColumn
(
"str"
,
"X"
);
tw
.
addColumn
(
"str"
,
"Y"
);
tw
.
addColumn
(
"str"
,
"Z"
);
tw
.
getColumn
(
0
)
->
cell
<
std
::
string
>
(
0
)
=
"a"
;
tw
.
getColumn
(
1
)
->
cell
<
std
::
string
>
(
0
)
=
"b"
;
tw
.
getColumn
(
2
)
->
cell
<
std
::
string
>
(
0
)
=
"c"
;
std
::
vector
<
std
::
string
>
colNames
{
"X"
,
"Z"
};
boost
::
scoped_ptr
<
ITableWorkspace
>
cloned
(
tw
.
clone
(
colNames
).
release
());
// Check clone is same as original.
TS_ASSERT_EQUALS
(
colNames
.
size
(),
cloned
->
columnCount
());
TS_ASSERT_EQUALS
(
tw
.
rowCount
(),
cloned
->
rowCount
());
TS_ASSERT_EQUALS
(
"a"
,
cloned
->
getColumn
(
0
)
->
cell
<
std
::
string
>
(
0
));
TS_ASSERT_EQUALS
(
"c"
,
cloned
->
getColumn
(
1
)
->
cell
<
std
::
string
>
(
0
));
}
void
test_toDouble
()
{
TableWorkspace
tw
(
1
);
tw
.
addColumn
(
"int"
,
"X"
);
...
...
Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
View file @
2fae76f2
...
...
@@ -242,6 +242,10 @@ private:
throw
std
::
runtime_error
(
"Cloning of TableWorkspaceTester is not implemented."
);
}
ITableWorkspace
*
doCloneColumns
(
const
std
::
vector
<
std
::
string
>
&
colNames
)
const
override
{
throw
std
::
runtime_error
(
"Cloning of TableWorkspaceTester is not implemented."
);
}
};
//===================================================================================================================
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment