Categories

Versions

You are viewing the RapidMiner Developers documentation for version 2024.0 - Check here for latest version

Adding Generation Rules to Output Ports

At this point, if you connect your operator with another operator that receives an IOTable object, it alerts the user that it hasn't received the correct object. This is because your operator hasn't yet done transformation of the meta data. It makes use of the meta data to check the preconditions, but doesn't deliver it to the output port. You can change this by adding generation rules in the constructor:

public MyOwnOperator( OperatorDescription description ){

    super(description);
    tableInput.addPrecondition(
        new ColumnSetPrecondition(tableInput, "test"));

    getTransformer().addRule(new TablePassThroughRule(tableInput, tableOutput, SetRelation.EQUAL));
}

This rule simply passes the received meta data to the output port, which causes the warning to vanish. However, the meta data doesn't reflect the actual delivered data since the operator adds a column. This should be reflected in the meta data, which is why you must implement a special transformation rule. To do so, use an anonymous class so that it looks like this:

getTransformer().addRule(
    new TablePassThroughRule(tableInput, tableOutput, SetRelation.EQUAL) {
        @Override
        public TableMetaData modifyTableMetaData(TableMetaData metaData) {
            return metaData;
        }
});

However, this only passes the received meta data to the output port, it doesn't account for changes to the meta data. By adding a hook, you can grab the meta data and change it so that it reflects the changes made on the data during operator execution. The following code adds a column named "newAttribute" to the TableMetaData. The column is configured to be of type real and with 0 missing values.

getTransformer().addRule(
    new TablePassThroughRule(tableInput, tableOutput, SetRelation.EQUAL) {
        @Override
        public TableMetaData modifyTableMetaData(TableMetaData metaData) {
            TableMetaDataBuilder builder = new TableMetaDataBuilder(metaData);
            builder.add("newAttribute", ColumnType.REAL, new MDInteger(0));
            return builder.build();
        }
});

If you change the type and name of a column, you can also change the meta data like this:

if (metaData.contains("test") == MetaDataInfo.YES) {
    ColumnInfo originalColumn = metaData.column("test");
    TableMetaDataBuilder builder = new TableMetaDataBuilder(metaData);
    builder.replace("test", ColumnType.DATETIME, originalColumn.getMissingValues());
    builder.rename("test", "newName");
    return builder.build();
}
return metaData;

You should change the meta data according to the changes of the data through your operator. Doing this will greatly improve the usability of your operator since correct meta data helps the user to understand what your oeprator's output is and how the next operator needs to be configured to handle the output.

If you don't know the details of the outgoing data but you know the output port type, you can add a very simple generation rule that defines the type delivered at the output port.

getTransformer().addGenerationRule(tableOutput, IOTable.class);

In the next step, you will learn how to use the PortExtender.