Jump to content

A Guide to Working with Capsule Properties


Joe Reckamp

Recommended Posts

  • Seeq Team

Capsules can have properties or information attached to the event. By default, all capsules contain information on time context such as the capsule’s start time, end time, and duration. However, one can assign additional capsule properties based on other signals’ values during the capsules. This guide will walk through some common formulas that can be used to assign capsule properties and work with those properties.

Note: The formula syntax used in the following examples will all be based on the formula language for Seeq version 49. If you have questions about errors you may be receiving in the formulas on different versions, please check out the What’s New in Seeq Knowledge Base pages for formula changes or drop a comment below with the error message.

How can I visualize capsule properties?

Capsule Properties can be added to the Capsules Pane in the bottom right hand corner of Seeq Workbench with the black grid icon. Any capsule properties beyond start, end, duration, and similarity that are created with the formulas that follow or come in automatically through the datasource connection can be found by clicking the “Add Column” option and selecting the desired property in the modal to get a tabular view of the properties for each capsule as shown below.

image.png

image.png

In Trend View, you can Capsule Property labels inside the capsules by selecting the property from the labels modal. Note that only Capsule Properties added to the Capsule Pane in the bottom right corner will be available in the labels modal.

image.png

In Capsule Time, the signals can be colored by Capsule Properties by turning on the coloring to rainbow or gradient. The selection for which property is performing the coloring is done by sorting by the capsule property in the Capsule Pane in the bottom right corner. Therefore, if Batch ID is sorted by as selected below, the legend shown on the chart will show the Batch ID values.

image.png

When working with Scorecard Metrics, you can use a Capsule Property as the header of a condition based scorecard by typing in the property name into the header modal:

image.png

How do I create a capsule for every (unique) value of a signal?

Let’s say you have a signal that you want to turn into individual capsules for each value or unique value of the signal. This is often used for string signals (e.g. batch IDs, operations, or phases) that may look like the signal below.

image.png

There’s two main operators that can be used for this:

$signal.toCapsules()

The toCapsules operator will create a capsule for each data point of the signal. Therefore, if there was only 1 data point per value in the string signal below, it would create one capsule per value, but if the string value was recorded every minute regardless of whether it change values, it would create 1 minute capsules. In addition, the toCapsules operator also automatically records a Capsule Property called ‘Value’ that contains the value of the signal data point.

$signal.toCondition('Property Name')

                The toCondition operator will create a capsule for each change in value of the signal. Therefore, in the case above where the value was recorded every minute regardless of value changes, it would only create one capsule for the entire time the value was equivalent. Similarly to the toCapsules operator, the toCondition operator also automatically records a Capsule Property called ‘Value’ that contains the value of the signal data point. However, with the toCondition operator, there’s an optional entry to store the property under a different name instead by specifying a property name in the parentheses in single quotes as shown in the example above.

Note: Sometimes when working with string signals of phases or steps that are just numbered (e.g. Phase 1), if there is only one phase in the operation, you may end up wanting two Phase 1 capsules in a row (e.g. Operation 1 Phase 1 and Operation 2 Phase 1) whereas the toCondition method above will only create a single capsule. In this instance, it can be useful to concatenate the operation and phase signals together to find the unique combination of Operations and Phases. This can be done by using the following formula:

($operationsignal + ': ' + $phasesignal).toCondition('Property Name')

How do I assign a capsule property?

Option 1: Assigning a constant value to all capsules within a condition

$condition.setProperty('Property Name', 'Property Value')

Note that it is important to know whether you would like the property stored as a string or numeric value. If the desired property value is a string, make sure that the ‘Property Value’ is in single quotes to represent a string like the above formula. If the desired value is numeric, you should not use the single quotes.

Option 2: Assigning a property based on another signal value during the capsule

For these operations, you will have to use a transform operator to perform a particular set of operations per capsule to retrieve the desired property. For example, you may want the first value of a signal within a capsule or the average value of a signal during the capsule. Below are some examples of options you have and how you would set these values to capsule properties. The general format for this operation is listed below where we will define some different options to input for Property Scalar Value.

$condition.transform($capsule -> $capsule.setProperty('Property Name', Property Scalar Value))

The following are options for what to input into Property Scalar Value in the formula above to obtain the desired property values:

First value of signal within a capsule:

$signal.toScalars($capsule).first()

Last value of signal within a capsule:

$signal.toScalars($capsule).last()

Average value of signal within a capsule:

$signal.average($capsule)

Maximum value of signal within a capsule:

$signal.maxValue($capsule)

Minimum value of signal within a capsule:

$signal.minValue($capsule)

Standard deviation of signal within a capsule:

$signal.stdDev($capsule)

Totalization of a signal within a capsule:

$signal.totalized($capsule)

Count the capsules of a separate condition within a capsule:

$DifferentCondition.count($capsule)

Duration of capsules in seconds of a separate condition within a capsule:

$DifferentCondition.totalduration($capsule)

There are more statistical operations that can be done if desired, but hopefully this gives you an idea of the syntax. Please leave a comment if you struggle with a particular operator that you are trying to perform.

Finally, there are often times when you want to perform one of the above operations, but only within a subset of each capsule. For example, maybe for each batch, you want to store the max temperature during just a particular phase of the batch. In order to do this, first make sure you have created a condition for that phase of the batch and then you can use the following to input into Property Scalar Value in the formula above:

$signal.within($PhaseCondition).maxValue($capsule)

In this case, the within function is cutting the signal to only be present during the $PhaseCondition so that only that section of the signal is present when finding the maximum value.

Option 3: Assign a property based on a parent or child condition

In batch processing, there is often a parent/child relationship of conditions in an S88 (or ISA-88) tree hierarchy where the batch is made up of smaller operations, which is then made up of smaller phases. Some events databases may only set properties on particular capsules within that hierarchy, but you may want to move the properties to higher or lower levels of that hierarchy. This formula will allow you to assign the desired property to the condition without the property:

$ConditionWithoutProperty.transform($capsule -> $capsule.setProperty('Current Property Name',
$ConditionWithProperty.toGroup($capsule).first().property('Desired Property Name')))

Note that this same formula works whether the condition with the property is the parent or child in this relationship. I also want to point out that if there are multiple capsules of the $ConditionWithProperty within any capsule of the $ConditionWithoutProperty, that this formula is set up to take the property from the first capsule within that time span. If you would like a different capsule to be taken, you can switch the first() operator in the formula above to last() or pick(Number) where last will take the property from the last capsule in the time span and pick is used to specify a particular capsule to take the property from (e.g. 2nd capsule or 2nd to last capsule).

There’s another write-up about this use case here for more details and some visuals:

 

How do I filter a condition by capsule properties?

Conditions are filtered by capsule properties using the keep operator. Some examples of this are listed below:

Option 1: Keep exact match to property

$condition.keep('Property Name', isEqualTo('Property Value'))

Note that it is important to know whether the property is stored as a string or numeric value. If the property value is a string, make sure that the ‘Property Value’ is in single quotes to represent a string like the above formula. If the value is numeric, you should not use the single quotes.

Option 2: Keep regular expression string match

$condition.keep('Property Name', isMatch('B*'))

$condition.keep('Property Name', isNotMatch('B*'))

You can specify to keep either matches or not matches to partial string signals. In the above formulas, I’m specifying to either keep all capsules where the capsule property starts with a B or in the second equation, the ones that do not start with a B. If you need additional information on regular expressions, please see our Knowledge Base article here: https://support.seeq.com/space/KB/146637020/Regex%20Searches

Option 3: Other keep operators for numeric properties

Using the same format of Option 1 above, you can replace the isEqualTo operator with any of the following operators for comparison functions on numeric properties:

isGreaterThan

isGreaterThanOrEqualTo

isLessThan

isLessThanOrEqualTo

isBetween

isNotBetween

isNotEqualTo

 

 

Option 4: Keep capsules where capsule property exists

$condition.keep('Property Name', isValid())

In this case, any capsules that have a value for the property specified will be retained, but all capsules without a value for the specified property will be removed from the condition.

How do I turn a capsule property into a signal?

A capsule property can be turned into a signal by using the toSignal operator. The properties can be placed at either the start timestamp of the capsule (startKey) or the end timestamp of the capsule (endKey):

 

$condition.toSignal('Property Name', startKey())

$condition.toSignal('Property Name', endKey())

This will create a discrete signal where the value is at the selected timestamp for each capsule in the condition. If you would like to turn the discrete signal into a continuous signal connecting the data points, you can do so by adding a toStep or toLinear operator at the end to either add step or linear interpolation to the signal. Inside the parentheses for the interpolation operators, you will need to add a maximum interpolation time that represent the maximum time distance between points that you would want to interpolate. For example, a desired linear interpolation of capsules may look like the following equation:

$condition.toSignal('Property Name', startKey()).toLinear(40h)

It should be noted that some properties that are numeric may be stored as string properties instead of numeric, particularly if the capsules are a direct connection to a datasource. In this case, a .toNumber() operator may need to be added after the toSignal, but before the interpolation operator.

Finally, it is often useful to have the property across the entire duration of the capsule if there are no overlapping capsules (e.g. when looking at batches on a particular unit). This is done by turning the signal into a step signal and then filtering the data to only when it is within a capsule:

$condition.toSignal('Property Name', startKey()).toStep(40h).within($condition)

What capsule adjustment/combination formulas retain capsule properties?

When adjusting or combining conditions, the rule of thumb is that operators that have a 1 to 1 relationship between input capsule and output capsule will retain capsule properties, but when there are multiple capsules that are required as the input to the formula operator, the capsule properties are not retained. For example, moving a capsule by 1 hour has knowledge of the input properties whereas merging 2 capsules together results in not knowing which capsule to keep the properties from. A full list of these operators and their stance on whether they retain or lose capsule properties during usage is below.

Operators that retain properties

Operators that lose properties

afterEnd

inverse

afterStart

merge

beforeEnd

fragment

beforeStart

intersect

ends

join

starts

union (if more than one capsule overlap)

middles

 

grow

 

growEnd

 

shrink

 

move

 

combineWith

 

encloses

 

inside

 

subtract

 

matchesWith

 

touches

 

union (when no capsules overlap)

 

 

It is important to note that capsule properties are attached to the individual capsule. Therefore, using a combination formula like combinewith where multiple conditions are combined may result in empty values in your Capsule Pane table if each of the conditions being combined has different capsule properties.

How do I rename capsule properties?

Properties can be swapped to new names by using the renameProperty operator:

$condition.renameProperty('Current Property Name', 'New Property Name')

A complex example of using capsule properties:

What if you had upstream and downstream processes where the Batch ID (or other property) could link the data between an upstream and downstream capsule that do not touch and are not in a specific order? In this case, you would want to be able to search a particular range of time for a matching property value and to transfer another property between the capsules. This can be explained with the following equation:

$UpstreamCondition.move(0,7d)

.transform($capsule ->{

  $matchingDownstreamProperty = ($DownstreamCondition.toSignal('Downstream Property to Match Name') == $capsule.property('Upstream Property to Match Name'))

  $firstMatchKey = $matchingDownstreamProperty.togroup($capsule,CAPSULEBOUNDARY.INTERSECT).first().startkey()

  $capsule.setProperty('Desired Property Name',$DownstreamCondition.toSignal('Desired Downstream Property Name').tostep(40h).valueAt($firstMatchKey))

  })

.move(0,-7d)

Let's walk through what this is doing step by step. First, it's important to start with the condition that you want to add the property to, in this case the upstream condition. Then we move the condition by a certain amount to be able to find the matching capsule value. In this case, we are moving just the end of each capsule 7 days into the future to search for a matching property value and then at the end of the formula, we move the end of the capsule back 7 days to return the capsule to its original state. After moving the capsules, we start the transform. Inside the transform, we find the matching downstream property by turning the capsule property to match from the downstream condition into a signal and match it to the capsule property from the upstream capsule. We then find the key (timestamp) of the first match of the property. Again, similar to some other things, the first option could be swapped out with last or pick to grab a different matching capsule property. Finally, we set the property on the upstream condition to 'Desired Property Name' by turning the downstream capsule property that we want into a step signal and take the value where the first match was found.

  • Like 4
Link to comment
Share on other sites

  • 10 months later...
  • Seeq Team

In v51, the "Assigning a property based on another signal value during the capsule" became much easier:

$condition.setProperty('Property Name', $signal, valueStat())

Where valueStat is one of the aggregation operations like average(), maxValue(), totalized(), etc.

This form is also much faster.

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

I have tried using

$signal.toCapsule()

on scalar string values. The batch ID comes with 2 timestamps, the first has a string value "Inactive" and the second has the batch name. How to I create a capsules in this case? I though that $signal.toCapsule() creates capsules all the way from one scalar point to the next, but it's not the case. 

 

Data:

Timestamp Value
Jan 22, 2022 11:23 AM
Inactive
Jan 22, 2022 11:23 AM 2022_Batch2
Feb 19, 2022 10:23 PM
Inactive
Feb 19, 2022 10:23 PM 2022_Batch3

I also have a picture, but I don't know how to attach to this forum.

 

Link to comment
Share on other sites

11 hours ago, Joe Reckamp said:

Hi vadeka,

Likely you need to filter out the invalid values first. Can you try doing the following formula?

$signal.validvalues().toCapsules()

 

Thank you Joe. I've tried using .validvalues(), but I didn't find how to specify what values are valid and which are invalid. I've tried to use .remove(), but the capsules did not stretch from from timestamp to the next, they were having same start and end time. I've summarize it into a new post here: Create Capsules from String Scalers.

 

Link to comment
Share on other sites

  • 1 month later...

This has been very helpful!  How would i string together multiple setProperties to add in more attributes associated with the capsules?    For example:  

$o2.removeLongerThan(40h).transform(
$capsule -> {$capsule.setProperty('OpeName', $o.toScalars($capsule).first()

I want to repeat this process on the same capsule for for "Batch).

thanks!

Link to comment
Share on other sites

  • Seeq Team

Hi Annie,

First, I'd recommend using the newer simplified version of setting the property as mentioned in Ben's comment above:

$o2.removeLongerThan(40h).setProperty('OpeName', $o, startvalue())

From there, you can simply string the setproperty operator along to add multiple properties:

$o2.removeLongerThan(40h).setProperty('OpeName', $o, startvalue()).setProperty('Batch', $b, startvalue())

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...