Back
Manager
Overview
The df::attributes::Manager class orchestrates attribute decomposition by managing multiple
Decomposer instances and providing unified access to decomposed attributes. It allows you to
break down complex data types (vectors, matrices, tensors) into their individual components for analysis
and visualization.
Include
#include <dataframe/attributes/Manager.h>
DecompDimension Enum
Controls the level of decomposition when querying attribute names or extracting components.
DecompDimension
namespace df::attributes {
enum class DecompDimension {
Scalar = 1, // Individual components (x, y, z, xx, xy, ...)
Vector, // N-dimensional vectors
Matrix // N-dimensional matrices/tensors
};
}
| Value | Description |
|---|---|
Scalar | Decompose into individual scalar components |
Vector | Decompose into vector-level groups |
Matrix | Decompose into matrix-level groups |
Manager Class
Manager API
namespace df::attributes {
class Manager {
public:
// Construct with a reference to a Dataframe
explicit Manager(const Dataframe& df);
// Copy constructor (deep-copies all decomposers)
Manager(const Manager& other);
// Add a decomposer to the manager
void addDecomposer(const Decomposer& decomposer);
// Get all decomposed attribute names for a given dimension
std::vector<std::string> getNames(DecompDimension targetDim) const;
// Get a decomposed attribute as Serie<T>
template <typename T>
Serie<T> getSerie(const std::string& name) const;
// Check if an attribute exists
bool hasAttribute(DecompDimension targetDim, const std::string& name) const;
// Clear all registered decomposers
void clear();
// Get the number of registered decomposers
size_t decomposerCount() const;
};
}
Basic Usage
Creating and Using a Manager
#include <dataframe/Serie.h>
#include <dataframe/algebra/types.h>
#include <dataframe/attributes/Manager.h>
#include <dataframe/attributes/Components.h>
#include <dataframe/attributes/Coordinates.h>
using namespace df;
// Create data
Serie<Vector3D> positions = {{1,0,0}, {0,1,0}, {0,0,1}};
Serie<Stress3D> stresses = {
{1, 2, 3, 4, 5, 6},
{7, 8, 9, 10, 11, 12}
};
// Build a Dataframe
Dataframe dataframe;
dataframe.add("P", positions);
dataframe.add("S", stresses);
// Create a Manager and register decomposers
attributes::Manager manager(dataframe);
manager.addDecomposer(attributes::Components());
manager.addDecomposer(attributes::Coordinates());
// Query available scalar names
auto names = manager.getNames(attributes::DecompDimension::Scalar);
// -> "Px", "Py", "Pz", "Sxx", "Sxy", "Sxz", "Syy", "Syz", "Szz",
// "P_x", "P_y", "P_z"
// Extract a specific component
auto px = manager.getSerie<double>("Px"); // Position X via Components
auto sxx = manager.getSerie<double>("Sxx"); // Stress XX component
Querying by Dimension
Decomposition at Different Levels
// Scalar-level: individual components
auto scalars = manager.getNames(attributes::DecompDimension::Scalar);
// For Vector3D "P": Px, Py, Pz
// For Stress3D "S": Sxx, Sxy, Sxz, Syy, Syz, Szz
// Vector-level: grouped as vectors
auto vectors = manager.getNames(attributes::DecompDimension::Vector);
// -> "P", "S"
// Matrix-level: grouped as matrices/tensors
auto matrices = manager.getNames(attributes::DecompDimension::Matrix);
// -> "S" (only matrix/tensor types)
// Check if a specific attribute exists
if (manager.hasAttribute(attributes::DecompDimension::Scalar, "Sxy")) {
auto sxy = manager.getSerie<double>("Sxy");
}
Complete Example
Full Workflow
#include <dataframe/Serie.h>
#include <dataframe/algebra/types.h>
#include <dataframe/attributes/Components.h>
#include <dataframe/attributes/Coordinates.h>
#include <dataframe/attributes/Manager.h>
#include <iostream>
using namespace df;
int main() {
// Create sample data
Serie<Vector3D> positions = {{1,0,0}, {0,1,0}, {0,0,1}};
Serie<Stress3D> stresses = {
{1, 2, 3, 4, 5, 6},
{7, 8, 9, 10, 11, 12}
};
Serie<Matrix4D> tensors = {
{1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16},
{1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16}
};
// Build dataframe
Dataframe dataframe;
dataframe.add("P", positions);
dataframe.add("S", stresses);
dataframe.add("T", tensors);
// Create manager and register decomposers
attributes::Manager manager(dataframe);
manager.addDecomposer(attributes::Components());
// List all scalar names
std::cout << "Scalar attributes:\n";
for (const auto& name : manager.getNames(
attributes::DecompDimension::Scalar)) {
std::cout << " " << name << "\n";
}
// Output:
// Px, Py, Pz
// Sxx, Sxy, Sxz, Syy, Syz, Szz
// T11, T12, T13, T14, T21, ..., T44
// Extract and use components
auto px = manager.getSerie<double>("Px");
auto sxx = manager.getSerie<double>("Sxx");
auto t12 = manager.getSerie<double>("T12");
std::cout << "\nPosition X: ";
for (size_t i = 0; i < px.size(); ++i) {
std::cout << px[i] << " ";
}
// Output: 1 0 0
std::cout << "\nStress XX: ";
for (size_t i = 0; i < sxx.size(); ++i) {
std::cout << sxx[i] << " ";
}
// Output: 1 7
return 0;
}