# Scorecard Metric with Signal Name / Display Signal Name for the Maximum of a number of Signals

Go to solution Solved by Nick Gigliotti,

## Recommended Posts

• Seeq Team
• Solution

As a user, I would like to be able to display the name of the maximum signal in an organizer this will help simplify troubleshooting. Is there anyway to do this?

This is relatively simple using Formula and the splice() function.

The main trick is getting the string value into the scorecard metric. This can be done by creating a scorecard metric with no statistics to create a scorecard that just displays the value of this string. I have shown an example of this below.

This functionality is very useful if you want to create a string signal that has more than one value. For example, say that I have three signals. I want to create a scorecard metric that tells me which of these three signals is the largest at any point in time.

I will start by creating a signal who's value at any given time is the corresponding name of the signal with the max value. This can be done relatively easy with formula using the max() and splice() functions.

Example Formula:

```\$maxValue =  \$s1.max(\$s2).max(\$s3)

'No Max'.splice('Signal1 is Max', \$s1 == \$maxValue)
.splice('Signal2 is Max', \$s2 == \$maxValue)
.splice('Signal3 is Max', \$s3 == \$maxValue)```

The following shows the result of the formula.

Finally, I'll use Simple Scorecard again to create a metric that displays this Max Signal for use in Organizer Topics.

Content Verified DEC2023

• 2
##### Share on other sites

• 6 months later...

Hi Nick,

Thanks for this tutorial, I was wondering if there was a way to achieve a similar result using the Max/Min functions?

I have several parameters each with 8 signals and I think doing the above for all of these may be more complicated for me than it needs to be.

For instance, I have 8 different pH results and my current scorecard will display the daily min, average & max value for these 8 signals but I would like to be able to also display which one of these signals was the min and max.

Any help would be great!

Cheers,

Isaac

##### Share on other sites

Thanks for your time and info Thorsten,

Unfortunately I do not think I have access to Python on my company profile, I have put a request in however.

Just to clarify, is all this required to achieve what Nick originally did in the initial post but with 8 signals? Can I not use the formula version of Deviation Search and increase the number of boundaries from 1 to 7 for example?

Many thanks,

Isaac

##### Share on other sites

Hi Isaac,

don't know why I did not came across this solution first, which is fairly the easiest to achive I think:

You can use boolean operators for this.

Determine Max Signal:

```\$days = days()

//Calculate maximum per day
\$aMax = \$a.aggregate(maxValue(), \$days, durationKey())
\$bMax = \$b.aggregate(maxValue(), \$days, durationKey())
\$gMax = \$g.aggregate(maxValue(), \$days, durationKey())
\$hMax = \$h.aggregate(maxValue(), \$days, durationKey())

//Which is max?
\$aIsMax = \$aMax > \$bMax && \$aMax > \$gMax && \$aMax > \$hMax
\$bIsMax = \$bMax > \$aMax && \$bMax > \$gMax && \$bMax > \$hMax
\$gIsMax = \$gMax > \$aMax && \$gMax > \$bMax && \$gMax > \$hMax
\$hIsMax = \$hMax > \$bMax && \$hMax > \$gMax && \$hMax > \$gMax

//Generate signal
"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMax)
.splice("Area B".toSignal(1d), \$bIsMax)
.splice("Area G".toSignal(1d), \$gIsMax)
.splice("Area H".toSignal(1d), \$hIsMax)```

Determine Min Signal:

```\$days = days()

//Caulate minimum per day
\$aMin = \$a.aggregate(minValue(), \$days, durationKey())
\$bMin = \$b.aggregate(minValue(), \$days, durationKey())
\$gMin = \$g.aggregate(minValue(), \$days, durationKey())
\$hMin = \$h.aggregate(minValue(), \$days, durationKey())

//Which is min?
\$aIsMin = \$aMin < \$bMin && \$aMin < \$gMin && \$aMin < \$hMin
\$bIsMin = \$bMin < \$aMin && \$bMin < \$gMin && \$bMin < \$hMin
\$gIsMin = \$gMin < \$aMin && \$gMin < \$bMin && \$gMin < \$hMin
\$hIsMin = \$hMin < \$bMin && \$hMin < \$gMin && \$hMin < \$gMin

//Generate Signal
"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMin)
.splice("Area B".toSignal(1d), \$bIsMin)
.splice("Area G".toSignal(1d), \$gIsMin)
.splice("Area H".toSignal(1d), \$hIsMin)```

Regards,

Thorsten

##### Share on other sites

Hi Thorsten,

Thanks again, that looks like a winner!

Only problem is we are still on R21.0.42.03 and I believe the use of those math operators are a feature of R21.044 and higher.

Are you aware of how to do the above formula in previous versions of Seeq?

##### Share on other sites

Hi Isaac,

Max:

```\$days = days()
\$aMax = \$a.aggregate(maxValue(), \$days, durationKey())
\$bMax = \$b.aggregate(maxValue(), \$days, durationKey())
\$gMax = \$g.aggregate(maxValue(), \$days, durationKey())
\$hMax = \$h.aggregate(maxValue(), \$days, durationKey())

\$aIsMax = \$aMax.isGreaterThan(\$bMax).intersect(\$aMax.isGreaterThan(\$gMax)).intersect(\$aMax.isGreaterThan(\$hMax))
\$bIsMax = \$bMax.isGreaterThan(\$aMax).intersect(\$bMax.isGreaterThan(\$gMax)).intersect(\$bMax.isGreaterThan(\$hMax))
\$gIsMax = \$gMax.isGreaterThan(\$aMax).intersect(\$gMax.isGreaterThan(\$bMax)).intersect(\$gMax.isGreaterThan(\$hMax))
\$hIsMax = \$hMax.isGreaterThan(\$aMax).intersect(\$hMax.isGreaterThan(\$bMax)).intersect(\$hMax.isGreaterThan(\$gMax))

"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMax)
.splice("Area B".toSignal(1d), \$bIsMax)
.splice("Area G".toSignal(1d), \$gIsMax)
.splice("Area H".toSignal(1d), \$hIsMax)```

Min:

```\$days = days()
\$aMin = \$a.aggregate(minValue(), \$days, durationKey())
\$bMin = \$b.aggregate(minValue(), \$days, durationKey())
\$gMin = \$g.aggregate(minValue(), \$days, durationKey())
\$hMin = \$h.aggregate(minValue(), \$days, durationKey())

\$aIsMin = \$aMin.isLessThan(\$bMin).intersect(\$aMin.isLessThan(\$gMin)).intersect(\$aMin.isLessThan(\$hMin))
\$bIsMin = \$bMin.isLessThan(\$aMin).intersect(\$bMin.isLessThan(\$gMin)).intersect(\$bMin.isLessThan(\$hMin))
\$gIsMin = \$gMin.isLessThan(\$aMin).intersect(\$gMin.isLessThan(\$bMin)).intersect(\$gMin.isLessThan(\$hMin))
\$hIsMin = \$hMin.isLessThan(\$aMin).intersect(\$hMin.isLessThan(\$bMin)).intersect(\$hMin.isLessThan(\$gMin))

"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMin)
.splice("Area B".toSignal(1d), \$bIsMin)
.splice("Area G".toSignal(1d), \$gIsMin)
.splice("Area H".toSignal(1d), \$hIsMin)```

Regards,

Thorsten

##### Share on other sites

Hi Thorsten,

Unfortunately it appears that the isGreaterThan function only works for scalars. Perhaps I need to try and get our version of Seeq updated!

Isaac

##### Share on other sites

• 3 weeks later...

Hi Isaac,

On version R21.0.43, you may still have to include the valuesearch(isgreaterthan(x)) syntax in your condition formulas. For your last comment, regarding isgreaterthan functions only working for scalars, the best way to handle this would be to take the difference between signals and compare that to zero, for example A is greater than B if (A-B)>0.

This slight modification of Thorsten's method may work for you:

Max:

```\$days = days()
\$aMax = \$a.aggregate(maxValue(), \$days, durationKey())
\$bMax = \$b.aggregate(maxValue(), \$days, durationKey())
\$gMax = \$g.aggregate(maxValue(), \$days, durationKey())
\$hMax = \$h.aggregate(maxValue(), \$days, durationKey())

\$aIsMax = (\$aMax-\$bMax).ValueSearch(isGreaterThan(0)).intersect((\$aMax-\$gMax).valueSearch(isGreaterThan(0))).intersect((\$aMax-\$hMax).valueSearch(isGreaterThan(0)))
\$bIsMax = (\$bMax-\$aMax).ValueSearch(isGreaterThan(0)).intersect((\$bMax-\$gMax).valueSearch(isGreaterThan(0))).intersect((\$bMax-\$hMax).valueSearch(isGreaterThan(0)))
\$gIsMax = (\$gMax-\$bMax).ValueSearch(isGreaterThan(0)).intersect((\$gMax-\$aMax).valueSearch(isGreaterThan(0))).intersect((\$gMax-\$hMax).valueSearch(isGreaterThan(0)))
\$hIsMax = (\$hMax-\$aMax).ValueSearch(isGreaterThan(0)).intersect((\$hMax-\$bMax).valueSearch(isGreaterThan(0))).intersect((\$hMax-\$gMax).valueSearch(isGreaterThan(0)))

"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMax)
.splice("Area B".toSignal(1d), \$bIsMax)
.splice("Area G".toSignal(1d), \$gIsMax)
.splice("Area H".toSignal(1d), \$hIsMax)```

Min:

```\$days = days()
\$aMin = \$a.aggregate(minValue(), \$days, durationKey())
\$bMin = \$b.aggregate(minValue(), \$days, durationKey())
\$gMin = \$g.aggregate(minValue(), \$days, durationKey())
\$hMin = \$h.aggregate(minValue(), \$days, durationKey())

\$aIsMin = (\$aMin-\$bMin).ValueSearch(isLessThan(0)).intersect((\$aMin-\$gMin).valueSearch(isLessThan(0))).intersect((\$aMin-\$hMin).valueSearch(isLessThan(0)))
\$bIsMin = (\$bMin-\$aMin).ValueSearch(isLessThan(0)).intersect((\$bMin-\$gMin).valueSearch(isLessThan(0))).intersect((\$bMin-\$hMin).valueSearch(isLessThan(0)))
\$gIsMin = (\$gMin-\$bMin).ValueSearch(isLessThan(0)).intersect((\$gMin-\$aMin).valueSearch(isLessThan(0))).intersect((\$gMin-\$hMin).valueSearch(isLessThan(0)))
\$hIsMin = (\$hMin-\$aMin).ValueSearch(isLessThan(0)).intersect((\$hMin-\$bMin).valueSearch(isLessThan(0))).intersect((\$hMin-\$gMin).valueSearch(isLessThan(0)))

"".toSignal(1d)
.splice("Area A".toSignal(1d), \$aIsMin)
.splice("Area B".toSignal(1d), \$bIsMin)
.splice("Area G".toSignal(1d), \$gIsMin)
.splice("Area H".toSignal(1d), \$hIsMin)```

Thanks,

Allison

• 2
##### Share on other sites

• Teddy changed the title to Scorecard Metric with Signal Name / Display Signal Name for the Maximum of a number of Signals