RELATE Operation
The RELATE operation is used to create relationships between existing things in the models such as hasLocation, or feeds.
Manifest Configuration
The configuration in the manifest file for the Relate operation has one parameter - the name of the skeleton input csv. The tool will look in the input_csvs folder for the named csv file. It is specified as:
{
"operation_type": "RELATE",
"config": {
"skeleton_file": "skeleton.csv"
}
}Skeleton
The CSV file used with the RELATE operation is referred to as the skeleton csv file.
This file works on the principle that entities within a row get related to other entities within the same row based on relationship details in the column headers. Relationships constructed in this way can represent many-to-many relationships across entities. Entities are identified in the same format as used within the CREATE operation (Model_ID|Entity_Name).
Examples
Unless otherwise noted, all the examples below use the following manifest file.
As the relate operation relates existing entities, the first operation in the manifest is a create operation (using the input_csvs/objects.csv also below). The various examples show the tool outputs as you provide different skeleton.csv files to the relate operation.
input_csvs/objects.csv
bld|test_building
Building
bld|maintenance
Room
bld|library
Library
bld|meter
Electrical_Meter
bld|fan
Fan
bld|power
Power_Sensor
bld|speed
Speed_Sensor
Example 1: Basic skeleton file
Each column header contains two required pieces of information and one optional description to aid readability. The mandatory information is the desired Brick relationship and a reference to the target column. By extending the csv with new columns and new rows there is no limit to the set of desired relationships that can be described between objects in a model.
Target column references are 'zero indexed' i.e the first column is referred to as column 0. To assist users the tool also recognises Excel-style column references, i.e. the first column can alternatively be referred to as column "A"
Inputs
skeleton.csv
(table below is shown with Excel style column and row numbering, but contents of the csv header row use numeric column references):
1
hasPart, 1
isPartOf, 0
hasLocation, 1
hasPoint, 4
isPointOf, 3
2
bld|test_building
bld|maintenance
bld|meter, bld|fan
bld|meter
bld|power
3
bld|test_building
bld|library
bld|fan
bld|speed
Understanding this skeleton file cell by cell:
Cell A2: According to the header in the Skeleton, the column A
hasPart, 1, (cell A2) is defines in the cellbld|test_building(which is a Brick Building if you look at theobjects.csvfile)hasPartwhatever is on the same row but in the column indexed by 1. In this case, because of the zero indexing of columns, column 1 refers to column B in the above table. Cell B2 is the room "bld|maintenance. So cell A2 defines the relationship of the entitybld|test_buildingwith a relation ofbrick:hasPartto the other entitybld|maintenance. In the resulting building model this would be represented as:bld:test_building brick:hasPart bld:maintenance .Cell A3: using the same logic as Cell A2, this defines the relationship:
bld|test_building brick:hasPart bld|library .Cell B2: The header in column B is
isPartOf, 0, so Cell B2 defines the relationshipbld|maintenancerelates tobld|test_buildingas an isPartOf relation. In the generated model, this will be represented as:bld|maintenance brick:isPartOf bld:test_building .Cell B3: similarly, create relationship:
bld|library brick:isPartOf bld|test_building .Cell C2: This shows how comma-separated lists can be used in a cell to relate multiple relationships to things at once. Column Header for column C is
hasLocation, 1, so cell C2 says say both the meter and the fan are in the maintenance room i.e. create both of these relationships:bld|meter brick:hasLocation bld|maintenance .bld|fan brick:hasLocation bld|maintenance .
Cell D2: Following the same pattern, the header of
hasPoint, 4asks for the triplebld|meter brick:hasPoint bld|power .Cell D3: similarly
bld|fan brick:hasPoint bld|speed .Cell E2: this generates the reverse link
bld|power brick:isPointOf bld|meter .Cell E3: this generates the link
bld|speed brick:isPointOf bld|fan .
Outputs
Zipping up the manifest, with a input_csvs folder containing both the objects.csv file and the skeleton.csv file and and running that through the tool will produce the following turtle output file, which contains all those triples:
Example 2: Alphabetic column references
To make it easier for modellers that create or manipulate CSVs using the popular Excel software it is possible to refer to columns using their alphabetic column name rather than the zero-indexed column number references.
The following skeleton.csv returns the same output model file as Example 1:
Inputs
skeleton.csv
(table below is shown with Excel style column and row numbering, and Excel style column references):
1
hasPart, B
isPartOf, A
hasLocation, A
hasPoint, E
isPointOf, D
2
bld|test_building
bld|maintenance
bld|meter, bld|fan
bld|meter
bld|power
3
bld|test_building
bld|library
bld|fan
bld|speed
Outputs
Example 3: Optional column descriptors
An optional human-readable description can be added to column headers. This information does not affect constructed models.
The following skeleton.csv returns the same output model file as Examples 1 & 2:
Inputs
skeleton.csv
(with optional header descriptors)
1
hasPart, B
the_rooms, isPartOf, A
the_equipment, hasLocation, B
hasPoint, E
the_points, isPointOf, D
2
bld|test_building
bld|maintenance
bld|meter, bld|fan
bld|meter
bld|power
3
bld|test_building
bld|library
bld|fan
bld|speed
Outputs
Example 4: Commenting out columns
As the skeleton CSVs can become complex the model generation tooling offers a way of commenting out/omitting columns. Starting a description in a column header with a # character means that the relationships for that column won't be made. Important to note though, is that relationships in other columns that reference things in the column will still be made.
Inputs
skeleton.csv
1
#, hasPart, B
the_rooms, isPartOf, A
the_equipment, hasLocation, B
hasPoint, E
#the_points, isPointOf, D
2
bld|test_building
bld|maintenance
bld|meter,bld|fan
bld|meter
bld|power
3
bld|test_building
bld|library
bld|fan
bld|speed
Outputs
The tool produces the following model output file, which contains fewer relationships than in the previous examples:
Example 5: Splitting the skeleton csv up for readability
As the skeleton files can become both very wide and very long they can be difficult to comprehend. It is highly recommended you split up the skeleton files into multiple files to help with comprehension. e.g., you may have one skeleton file that describes the hasPart relationships between all the locations, and another that covers the same relationship for equipment and another for the feeds relationship, etc.
This example splits the skeleton csv up into three separate files. How to split files up is an arbitrary choice but in this instance one csv declares the relationships between locations and other locations, one csv declares the relationships between equipment and locations and one that declares the relationships concerning points. To produce the full model the Relate operation needs to be run three times, once with each skeleton csv file i.e. declared three times in the manifest:
Inputs
input_csvs/skeleton_locations.csv
1
hasPart, B
isPartOf, A
2
bld|test_building
bld|maintenance
3
bld|test_building
bld|library
input_csvs/skeleton_equipment.csv
1
#, isLocationOf, B
hasLocation, A
2
bld|maintenance
bld|meter, bld|fan
input_csvs/skeleton_points.csv
1
hasPoint, B
isPointOf, A
2
bld|meter
bld|power
3
bld|fan
bld|speed
Outputs
The tool results in the same outputs as examples 1-3, demonstrating that splitting the skeleton CSV into multiple files is an effective way to divide your model without impacting on the quality of the model.
Last updated