Back

Coordinates Decomposer

Overview

The Coordinates decomposer specializes in extracting spatial coordinate components from vector types. Unlike Components, it uses an underscore separator and allows customizable coordinate names (defaulting to x, y, z).

Include
#include <dataframe/attributes/Coordinates.h>

Class Definition

Coordinates API
namespace df::attributes {

class Coordinates : public GenDecomposer<Coordinates> {
public:
    // Construct with custom coordinate names (default: {"x", "y", "z"})
    explicit Coordinates(
        const std::vector<std::string>& coordNames = {"x", "y", "z"});

    Strings names(
        const Dataframe& dataframe,
        DecompDimension targetDim,
        const SerieBase& serie,
        const String& name) const override;

    Serie<double> serie(
        const Dataframe& dataframe,
        DecompDimension targetDim,
        const std::string& name) const override;

private:
    std::vector<std::string> coordNames_;
};

}

Naming Convention

Coordinates uses underscore separation: {name}_{coord}

TypeDefault Names
Vector2D{name}_x, {name}_y
Vector3D{name}_x, {name}_y, {name}_z
Vector4D{name}_x, {name}_y, {name}_z, {name}_w (if 4 names provided)

Only vector types (Vector2D, Vector3D, Vector4D) are supported. Matrix and tensor types are ignored by this decomposer.

Examples

Default Coordinate Names
using namespace df;

Serie<Vector3D> positions = {{1,2,3}, {4,5,6}, {7,8,9}};

Dataframe df;
df.add("P", positions);

attributes::Manager mgr(df);
mgr.addDecomposer(attributes::Coordinates());

// Scalar decomposition: "P_x", "P_y", "P_z"
auto names = mgr.getNames(attributes::DecompDimension::Scalar);

auto px = mgr.getSerie<double>("P_x");  // {1, 4, 7}
auto py = mgr.getSerie<double>("P_y");  // {2, 5, 8}
auto pz = mgr.getSerie<double>("P_z");  // {3, 6, 9}
Custom Coordinate Names
using namespace df;

Serie<Vector3D> positions = {{1,2,3}, {4,5,6}};

Dataframe df;
df.add("P", positions);

// Use custom names (e.g., geographic coordinates)
attributes::Manager mgr(df);
mgr.addDecomposer(attributes::Coordinates({"easting", "northing", "elevation"}));

// Scalar decomposition: "P_easting", "P_northing", "P_elevation"
auto names = mgr.getNames(attributes::DecompDimension::Scalar);

auto easting = mgr.getSerie<double>("P_easting");    // {1, 4}
auto northing = mgr.getSerie<double>("P_northing");  // {2, 5}
auto elev = mgr.getSerie<double>("P_elevation");     // {3, 6}
Combining with Components
using namespace df;

Serie<Vector3D> positions = {{1,2,3}, {4,5,6}};
Serie<Stress3D> stresses = {{100,20,10,80,15,60}, {110,25,12,85,18,65}};

Dataframe df;
df.add("P", positions);
df.add("S", stresses);

// Register both decomposers
attributes::Manager mgr(df);
mgr.addDecomposer(attributes::Components());
mgr.addDecomposer(attributes::Coordinates());

auto names = mgr.getNames(attributes::DecompDimension::Scalar);
// Components gives: "Px", "Py", "Pz", "Sxx", "Sxy", ...
// Coordinates gives: "P_x", "P_y", "P_z"
// (Coordinates ignores stress tensors)

// Both decomposers provide position X, with different name patterns
auto px1 = mgr.getSerie<double>("Px");    // via Components
auto px2 = mgr.getSerie<double>("P_x");   // via Coordinates
// Both return the same data: {1, 4}

Coordinates vs Components

FeatureCoordinatesComponents
Supported typesVectors onlyVectors, matrices, tensors
Naming pattern{name}_{coord}{name}{suffix} (no separator)
Custom namesYes (constructor parameter)No (fixed conventions)
Use caseSpatial/geographic coordinatesGeneral component extraction