Table workspaces are general purpose workspaces for storing data of mixed types. A table workspace is organized in columns. Each column has a name and a type - the type of the data in that column. Data can be accessed by column, by row, or by cell
For full details of the Table Workspaces python type itself please see this page
.
The methods for getting a variable to an Table Workspace is the same as shown in the Workspace help page.
If you want to check if a variable points to something that is an Table Workspace you can use this:
from mantid.api import ITableWorkspace
tableWS = CreateEmptyTableWorkspace()
if tableWS is ITableWorkspace:
print(tableWS.getName() + " is a " + tableWS.id())
Output:
tableWS is a TableWorkspace
Most of the time Table workspaces are the output of certain algorithms, but you can create them yourself should you wish.
from mantid.kernel import V3D
# Create PositionTable
tableWS = CreateEmptyTableWorkspace()
# Add some columns, Recognized types are: int,float,double,bool,str,V3D,long64
tableWS.addColumn(type="int",name="Detector ID",plottype=6)
tableWS.addColumn(type="str",name="Detector Name",plottype=6)
tableWS.addColumn(type="V3D",name="Detector Position",plottype=6)
tableWS.addColumn(type='float',name="Value",plottype=2)
tableWS.addColumn(type='float',name="Error",plottype=5)
tableWS.setLinkedYCol(4, 3)
# Populate the columns for three detectors
detIDList = range(1,4)
detPosList = [ V3D(9.0,0.0,0.0), V3D(10.0,3.0,0.0), V3D(12.0,3.0,6.0)]
for j in range(len(detIDList)):
nextRow = { 'Detector ID': detIDList[j],
'Detector Name': "Detector {0}".format(detIDList[j]),
'Detector Position': detPosList[j],
'Value': 10,
'Error': 1 }
tableWS.addRow ( nextRow )
#setup as above
# Rows
print("Row count: {}".format(tableWS.rowCount()))
print("Detector Position: {0}, Detector Name: {1}, Detector ID: {2}".format(
tableWS.row(0)["Detector Position"],
tableWS.row(0)["Detector Name"],
tableWS.row(0)["Detector ID"])) # row values as a dictionary
# Resize the table
tableWS.setRowCount(4)
# Add Rows
tableWS.addRow( [2, "new Detector 1", V3D(2,2,2)])
# or using a dictionary
nextRow = { 'Detector ID': 5,
'Detector Name': "new Detector 2",
'Detector Position': V3D(5,5,5) }
tableWS.addRow ( nextRow )
# Columns
print("Column count: {}".format(tableWS.columnCount()))
print("Column names: {}".format(tableWS.getColumnNames()))
columnValuesList = tableWS.column(0)
# convert table to dictionary
data = tableWS.toDict()
print("Detector names: {}".format(data['Detector Name']))
# To remove a column
tableWS.removeColumn("Detector Name")
Table workspaces can be easily converted to a pandas DataFrame
using the following code snippet.
import pandas as pd
df = pd.DataFrame(table.toDict())
If only a subset of the data from the table is required, or you’re working with an existing DataFrame
and want to append columns from the Table workspace this can be achieved as follows.
df = pd.DataFrame()
for col in tableWS.getColumnNames():
df[col] = tableWS.column(col)
A TableWorkspace may be pickled <https://docs.python.org/2/library/pickle.html/> and de-pickled in python. Users should prefer using cPickle over pickle, and make sure that the protocol option is set to the HIGHEST_PROTOCOL to ensure that the serialization/deserialization process is as fast as possible.
import cPickle as pickle
pickled = pickle.dumps(ws2d, pickle.HIGHEST_PROTOCOL)
Table workspaces can be created using the workspace factory:
ITableWorkspace_sptr table = WorkspaceFactory::Instance().createTable("TableWorkspace");
Columns are added using the addColumn method:
table->addColumn("str","Parameter Name");
table->addColumn("double","Value");
table->addColumn("double","Error");
table->addColumn("int","Index");
Here the first argument is a symbolic name of the column’s data type and the second argument is the name of the column. The predefined types are:
Symbolic name | C++ type |
---|---|
int | int |
float | float |
double | double |
bool | bool |
str | std::string |
V3D | Mantid::Geometry::V3D |
long64 | int64_t |
vector_int | std::vector<int> |
vector_double | std::vector<double> |
The data in the table can be accessed in a number of ways. The most simple way is to call templated method T& cell(row,col), where col is the index of the column in the workspace and row is the index of the cell in the column. Columns are indexed in the order they are created with addColumn. There are also specialized methods for four predefined data types: int& Int(row,col), double& Double(row,col), std::string& String(row,col), bool& Bool(row,col). Columns use std::vector to store the data. To get access to the vector use getVector(name). To get the column object use getColumn(name).
Only columns of type int, double and str can currently be saved to Nexus by SaveNexus or SaveNexusProcessed. Columns of other types will simply be omitted from the Nexus file without any error message.
Cells with the same index form a row. TableRow class represents a row. Use getRow(int) or getFirstRow() to access existing rows. For example:
std::string key;
double value;
TableRow row = table->getFirstRow();
do
{
row >> key >> value;
std::cout << "key=" << key << " value=" << value << std::endl;
}
while(row.next());
TableRow can also be use for writing into a table:
for(int i=0; i < n; ++i)
{
TableRow row = table->appendRow();
row << keys[i] << values[i];
}
Users can define new data types to be used in TableWorkspace. TableColumn.h defines macro DECLARE_TABLECOLUMN(c_plus_plus_type,symbolic_name). c_plus_plus_type must be a copyable type and operators << and >> must be defined. There is also DECLARE_TABLEPOINTERCOLUMN macro for declaring non-copyable types, but it has never been used.
Category: Concepts