Jump to content
  • To Search the Seeq Knowledgebase:

    button_seeq-knowledgebase.png.ec0acc75c6f5b14c9e2e09a6e4fc8d12.png.4643472239090d47c54cbcd358bd485f.png

Search the Community

Showing results for tags 'formula'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Community Technical Forums
    • Tips & Tricks
    • General Seeq Discussions
    • Seeq Data Lab
    • Seeq Developer Club
    • Seeq Admin Forum
    • Feature Requests

Categories

  • Seeq FAQs
  • Online Manual
    • General Information

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Company


Title


Level of Seeq User

  1. Is there a way to automate generating signals in Seeq using a experimental lookup table? As of now for a particular use case, we are able to generate signals from an experimental lookup table where the table was constructed in excel first and then copied/pasted into formula within a workbench where it is then executed to generate the signal. However, the data within the experimental lookup table is from a separate spreadsheet that gets updated per day so if a specific key has it's value changed, we would have to manually go into the lookup table and change that corresponding value for the specific key and then re-execute. I know in data lab, spy.pull() can have a calculation argument or you can specify a formula to be applied. Any help or suggestions would be much appreciated. Thanks!
  2. This video demonstrates various formula functions in Seeq to calculate the rate of change or change in behavior in a process variable by leveraging the .derivative(), .runningDelta(), and .isDelta() formula functions.
  3. Batch Cycle Time Analysis is a core requirement for any batch process. In this example use case, we will explore how to identify various phases of the process, summarize the findings in tables and visualize data at scale using assets using Seeq.
  4. FYI, I'm very much self-taught in Python and don't use it more than a few times a month. I work as a technology licensor and our customers have provided datasets for us to work on. Most of our process units have enough similarities that we can templatize SEEQ formulas and then SEEQ workbooks. Thus once I've completed the following work for one customer, I'm 80% of the way done for the next 100+ customers. I'm struggling to get the formulas pushed back into SEEQ from the DataLab. I've imported CSVs of data into SEEQ until we get our PI-to-PI connect setup to pull directly from our customer to our PI Asset Framework and then pushed to our SEEQ instance. Since generating the template formulas is MUCH easier in Excel, I've created all the "Name", "Formula", "Formula Parameters" as strings in an Excel workbook and imported it as a Dataframe "calc_signals" into DataLab. Here's the relevant code: As you can see in Row 1, The Formula Parameter array is empty for the signal $OFPOF. This is the formula generated for the row above, Row 0. This is because I haven't pushed it to SEEQ. You can see the error in the image below. Do I need to actually push each row to SEEQ and then search again to get this to work right? I don't have a huge set of calculations, but it seems there should be a better way. Once I sort through this error, I see that I will have troubles later since SEEQ automatically generates the signal variable name "$OFPOF". Is there a way to override existing variable names and assign new calculations a variable name of my choice?
  5. I write results of my simulation to historian and consequently I use them in Seeq as inputs for formulas. If I rewrite historian data (by running simulation again), then raw data in Seeq are reloaded, however results of formulas related to these inputs are not refreshed automatically. Only option I found is to change formula input to different variable and consequently configure correct input variable. How can I refresh formula outputs more efficiently?
  6. Hello, Does there exist a method to pull the data with some of them need to be applied with a formula? For example, I want to pull several signals all at once, including "SP", "MODE", "OUT", "PV". For SP and MODE, these attributes are categorical, so there are only four possibilities, for instance, for their values, which are 0, 1, 8, 9. However, with spy.pull() function, these attributes will be interpolated. So I have to pull first the data for "OUT", "PV", and again pull the data for "SP" and "MODE" with a parameter "calculation", as follows: # My current method is with 2 pull functions, but they took too much time for many signals my_pull_1 = spy.pull( my_search.query("Name not in ('MODE', 'SP')"), start=start, end=end, grid=grid, ) my_pull_2 = spy.pull( my_search.query("Name in ('MODE', 'SP')"), start=start, end=end, grid=grid, calculation="$signal.toStep()" ) Since in my_search dataframe, there could be thousands of different "MODE" and "SP" signals, pulling the data twice will be very slow. Is there a way that I can pull only once the data, and apply the function to only part of the signals, like defining the formula parameter for the function? # what I would like to realize is something like this my_pull = spy.pull( my_search, start=start, end=end, grid=grid, formula="$Mode.toStep()", formula_parameters={ "$Mode": my_search[my_search['Name'] == 'MODE'] } ) Thanks in advance, Siqi
  7. When adding properties to capsules I sometimes get this error, it is fairly random across many different PI tags in different servers. I believe it may be related to seeq version R61.1.6 as I have only just started seeing it. It is consistent for the tag and time period that the error occurs for. This is the offending seeq formula. The signals in question trend just fine in Seeq. $condition.setProperty('CO (minimum)', $co, minValue()) .setProperty('CO (maximum)', $co, maxValue()) .setProperty('O2 (minimum)', $o2, minValue()) .setProperty('O2 (maximum)', $o2, maxValue()) I am sure there is something that needs to be fixed here in Seeq or PI to resolve this correctly, but I am looking for a crafty workaround I can use in the short term while our IT support figures this out. Any ideas much appreciated!
  8. Dear community, I want to identify representative capsules based on the capsule duration. What I did so far is: 1. Identify capsules 2. Create a signal from condition that represents the capsule duration. 3. Calculate average capsule duration and percentiles of interest from this signal using metrics 4. Use these metrics to identify capsules that are within a certain range around the average or between two percentiles. What I would like to do next and could not accomplish so far is: By now step 4 works when entering the respective criterion to a value search by hand. Now I would like to do that dynamically, i.e., calculate the metrics for the displayed time range and directly get capsules that satisfy the criterion given above. After trying around for some time, this seems to be possible using formula: I tried to use the metrics directly, but the function I tried to use (InBetween) does not accept metrics as input. I also tried to calculate the metrics directly in formula to avoid wrong data types, but that was also not successful. It sems to get down to explicitly convert the signal metrics to scalar, but I also fail to do that. As I am quite new to seeq, I would appreciate if there were some hints on this: Is it possible? Did I choose the correct approach? Are there other, even simpler ways to accomplish that. Thanks in advance!
  9. I am trying to create a condition that displays most recent 20 batches in the last month. Is there a good way to do this? I am currently using the below formula, but I get the error Uncertain Scalars cannot be used as thresholds for ScalarPredicates at 'isGreaterThanOrEqualTo', because it seems my $earliest_start is always an uncertain value. $capsule = capsule(now() - 1month, now()) $selected = $batch_condition.toGroup($capsule,CapsuleBoundary.EnclosedBy).pick(-20) $earliest_start = $selected.startKey() $batch_condition.removeLongerThan(40h).keep('Start',isGreaterThanOrEqualTo($earliest_start)) Is there any way I can fix this issue or get the most recent 20 batches another way?
  10. When pushing Formulas to Workbench from Data Lab, you can use "\" and "\n" in a few different ways in the Data Lab code, to create a nicely formatted, multi-line Formula in Workbench: For the Formula pushed to Workbench, a \n can be used for a line return. This is valuable for creating multi-line Formulas with intermediate variable assignments, or for making lengthy, single lines of code more readable. For the Formula pushed to Workbench, a \ can be used just before a single quote, when you need to include a single quote in the Formula. This helps for example when working with string signals. On the Data Lab side, using a \ at the end of the line continues the code to the next line, helping with readability in Data Lab. These are illustrated in the Data Lab code below which pushes a condition Formula to Workbench: Editing the Formula in Workbench, the Formula appears as we desired:
  11. Dear All, In python I have the following logic what I'd like to translate to Seeq formula. np.where((testdf['Signal_1']) < 0, testdf['Signal_2'], np.where((testdf['Signal_1']) < 30, testdf['Signal_2'], testdf['Signal_1'])) I know it would possible with capsules but it is only one leg of the whole solution and I think it's obscure to have 20-30 capsules for only one calculation what we use at others too.
  12. A question came up recently that I thought would be of wider interest: how can I prevent interpolation across batch/capsule boundaries? In batch processes, lab samples are often taken periodically throughout the course of a batch. When viewing these samples in Seeq, you may encounter times when samples are interpolating between batches rather than just within a batch. In the image below, the periods highlighted in yellow correspond to this unwanted interpolation. The following formula is one way of preventing this interpolation. $signal corresponds to your signal of interest and $condition corresponds to your batches you want to prevent interpolation across. combineWith( $signal, Scalar.Invalid.toSignal().aggregate(startValue(), $condition.removeLongerThan(40h), startKey()) ) This results in the following signal that has our desired behavior:
  13. Use Case: It is common in industry to seek to use the behavior of upstream process variables to predict what the behavior of a downstream variable might be minutes, hours or days from the present time. Solution: A traditional predictive modeling workflow can be applied to solve this problem. Identify an appropriate training data set Perform any necessary data cleansing Create a predictive model Evaluate the model fit Improve the model Operationalize the model What differentiates this use case from any other predictive modeling use case is a specific data cleansing step for adjusting signals to remove process lag. 1. Load Data Load your target signal and the relevant upstream signals into the display pane. In this example, the target signal is the product viscosity, measured in an analytical lab based off a sample from a downstream sample point. Three upstream signals: the reactor temperature, reactant conversion, and viscosity modifier flow to the reactor significantly influence the product viscosity measurement and will be used as inputs into the model signal. 2. Identify Training Data Set Identify an appropriate training data set for your regression model. This may involve a longer time window to include variability in product type or seasonality. In this example, we will pan out to 3 months to capture multiple cycles of different product types. With an appropriate training window identified, you can also limit your training data set to a subset of samples present during a particular condition. If this interests you, consult the "advanced options" section of the Prediction Tool KB article for more information. This method is particularly useful if you're wishing to create different models for different modes of operation. 3. Cleanse Signals -- Adjust for Process Lag We can time-shift our upstream signals using either a known constant delay, a known variable delay (like a calculated residence time signal), or an unknown delay of maximum correlation to the target signal. The first two of these options will utilize the .move() function in Formula (or .delay() in earlier versions of Seeq). The latter will utilize the .correlationOffset() function. In this example, we have a known lag of 1.5 hours between the reactor and the product sampling point. We will use the move function with an input scalar of 1.5h, as shown below. The time shift calculation should be applied across all relevant input signals. More information on the different options for time shifting signals using fixed, variable, or calculated offsets is available in this forum post: 4. Cleanse Signals -- Remove signal noise, outliers, abnormal operating data In this example, we apply an agileFilter to each of our time-shifted model input signals. Apply the same technique to each of the model inputs. Note that steps 3 & 4 could have been combined into a single formula. An example of this would be: $reactor_temp.move(1.5h).agileFilter(1min) For guidance on additional cleansing techniques, consult the Interactive Training. 5. Build the Predictive Model Use the Prediction tool panel to create a model of your target signal based on your cleansed, time-adjusted input signals. Ensure your model training window matches the date range that you identified in step 2. You can view the model parameters like coefficients, rSquared, and p-values using the "+ Prediction Model" option. 6. Evaluate the Model Fit Use Scatter Plot view and the model parameters to evaluate the goodness of fit of the model. Switch to a time range outside of your training data set to ensure your model is a good fit for data throughout time. 7. Improve Model (as needed) If the scatter plot indicates a non-linear relationship, test out additional model scales in the prediction tool panel. Consider eliminating variables with p-values higher than your significance level cutoff (frequently 0.05). Add additional variables if relevant. If distinct modes of operation introduce significant signal variability, consider creating a model for each operating mode and stitch the models together into a single model using the splice() function in Formula. 8. Deploy the Model The model should project out into the future by the amount of the process lag between the upstream and target signals.
  14. FAQ: I have a condition for events of variable duration. I would like to create a new condition that comprises the first third of the time (or 4th, or 10th) of the original condition. Solution: A stepwise approach can be taken to achieve this functionality. 1. Begin with your condition loaded in the display pane. 2. Create a new Signal using Signal from Condition that calculates the total duration of each of your event capsules, interpolated as a step signal. 3. Create a new signal that is your total event duration multiplied by the proportion of the event that you would like to capture. e.g. for the first 1/3 of the event, divide your total duration signal by 3, as shown below. 4. Create an arbitrary discrete signal with a sample at the start of each of your event capsules. 5. Shift the arbitrary discrete signal in time by the value of your signal calculated in step 3. In this example, the 1/3 duration signal. Note, depending on your version of Seeq, the function to do this may be called move() or delay(). 6. Use the toCapsules() function in Formula to create a tiny (zero duration) capsule at each of your shifted, discrete samples. 7. Join the start of your original condition with the capsules created in step 6 using the composite condition tool.
  15. FAQ: I have a signal with a gap in the data from a system outage. I want to replace the gap with a constant value, ideally the average of the time period immediately before the data. Solution: 1. Once you've identified your data gaps, extend the capsules backwards by the amount over which time you want to take the average. In this example, we want to fill in the gap with the average of the 10 minutes before the signal dropped, so we will extend the start of the data gap capsule 10 minutes in the past. This is done using the move function in Formula: $conditionForDataGaps.move(-10min,0min) 2. Use Signal from Condition to calculate the average of the gappy signal during the condition created in step 1. Make sure to select "Duration" for the timestamp of the statistic. 3. Stitch the two signals together using the splice function. The validvalues() function at the end ensures a continuous output signal. $gappysignal.splice($replacementsignal,$gaps).validvalues()
  16. I have an interesting question that I need some assistance on. We have a signal that generally has no dominant frequency. However, it sometimes does get a dominant frequency and when it does, we are really interested in two things: What is the dominant frequency? How dominant is it? ( Let's call this "magnitude." ) Tracking both the dominant frequency and the intensity over time using a rolling 2 to 3 hour window every 5 minutes. This value has predictive capability when it does show up, and it intensifies as it gets closer to a particular event we are trying to predict. I've been able get the peak frequency because the formulas are clear enough to figure this out. The problem is the magnitude. The "Frequency Analysis" panel results show something like this: How do I get that peak value? I don't want to have to specify a hard-coded frequency band for this. The problem is that I don't see a function for that. I can call the fft() function in a way in which it returns a "Table" type. signal.fft ( bounds , period , units ) : Table Create a table of frequency magnitudes by analyzing the signal in the bounds. The table will have 2 columns, frequency and magnitude. Then I can use the top() function to return the top 1 row ordered by the greatest "magnitude" column: table.top ( limit , columnName , direction ) : Table However, I cannot for the life of me figure out how to get the "mangitude" value out of the first row returned in "Table" the above function and convert it into a sample at the ending point of the rolling 3 hour/5min period. Is this even possible. Is there a better way? // Getting a rolling 3 hour window every 5 minutes. $periods = periods(3h, 5min) // for condition, get a signal with samples ending at each capsule representing: // key: end of 3hr window // value: peak magnitude of the fft of the $waveSignal $periods.transformToSamples( $cap -> { // excute the expression for each capsule in condition. $tbl = $waveSignal.fft($cap, 1s, 's') // want the results in period lengths, not frequencies. // get the largest magnitude, filtering for the frequency/period length range of interest // get the first row of that table. $r = $tbl.filter('frequency'. isBetween(30s, 150s)) .top(1, 'magnitude', 'desc') .getFirstRow() // *******HOW DO I DO THIS???****** // convert that magnitude calculated to sample located at the end of this capsule. sample($cap.getEnd(), $r.get('magnitude')) } ) Thanks in advance! Even better would be: getting the sum of the values in the peakFrequency +-/ 2s window.
  17. Hello, I am trying to create a polynomial formula using the formula tool but I get the following error message "t is not compatible with t² at" with 'add' or 'subtract' after. Same with t² and t³. How can I create such formula? Example: 2 * $a^3 + 5 * $a^2 - 8 * $a + 200
  18. Hi, Is it possible to calculate the duration of valve opening (from time when change from "close" to "not close" to time when change from "not close" to "close") I've tried to do this by derivative function, but the values are string type. For the period of time, e.g. a year need to receive the number of the scalar values of these periods and then perform some calculations with formula with each of that scalar value.
  19. Hey there, My question splits into two parts: Firstly, I want to create a condition based on multiple criteria: if signal A equal to 3, B equal to 4, C is greater than 5 than condition is valid. I know i could create 3 individual capsule and overlap them. Is there a simple way to use formula to do so? Secondly, in my analysis i have 10 signals and associated conditions(alert), then I want to know in the past 7 days how many alert in total(repeated instance or capsule doesnt count) ? and How long is the total alert time? Thank you
  20. Background: When looking to identify trends or step changes in a signal, we typically recommend an approach of smoothing the signal, taking the first derivative, then identifying when that derivative is positive or negative. This method works well most of the time, but employing this technique in combination with others can be more effective at capturing trends/step changes when the value change in the signal is more subtle. Solution: When looking for step changes, we can use a technique of calculating a range of the signal on a rolling periodic basis and search for when the range exceeds some limit. We can then combine this condition with when the derivative is positive (increasing step changes) or negative (decreasing step changes) to capture our final condition. 1. Create a rolling window over which you will look at the range (max-min value) of the signal. In my example I used a 4h window every 30 minutes, because my tank draining events were typically never longer than 4h. Select the smallest time period that you can that is still longer than your longest draining event. 2. Use Signal from Condition to calculate the range (max-min) of your signal over each of the rolling windows. Make sure to place the time stamp of the statistic at the end of each rolling capsule. 3. Identify time periods when that range calculation is above some threshold. In this example we used a threshold of 2 based looking at the trend output of our step 2. If we zoom in on a smaller range of time, we see that our capsules for when the range value is high actually extend beyond the completion of our decreasing signal. 4. We can intersect this condition that we have identified for high range in the signal with a condition for when the derivative of the signal is negative to capture our desired events. First calculate the first derivative of the signal. We apply a smoothing agileFilter in this step as well to remove signal noise. 5. Identify when that derivative value is less than zero using the value search tool. 6. Now take the intersection of the condition for negative derivative of the level and the condition for high range. The final view of the original signal and the events identified: Use chain view to validate your calculations:
  21. As a Seeq user, you may have created a condition for a particular event of interest and would like to create a signal that is the running count of these events over a given time period. This analysis is common in equipment fatigue use cases when equipment degrades slowly based on a number of cycles (thermal, pressure, tension, etc) that it has undergone during it's life or since a last component replacement. This use case can be done very efficiently in Seeq Formula. The assumptions for the below solution are: You have a condition ($condition) of interest that you would like to understand the running count for There is a defined timeframe of interest, where counting will start and end. Note the end date can be sometime in the future. For the below example, this condition is referenced as $manualCondition, but could very well be another condition that wasn't created via the Manual Condition tool. Just note that for each capsule in this condition, the count will restart at 0. Solution - Utilize the runningCount() formula function: 1) runningCount() currently only accepts signals as inputs, so convert your $condition to a signal by using .toSignal(), which produces a single sample for each capsule: $condition.toSignal(SAMPLE_PLACEMENT) SAMPLE_PLACEMENT should be specified as startKey(), middleKey(), or endKey(). If you want your count to increase at the start of each event, then use startKey(). If wanting the count to increase in the middle or end of each event, then use middleKey() or endKey() 2) Use the runningCount() function on the signal created above. $signal.runningCount($conditionToStartAndEndCounting) Both steps are shown below in a unified Formula: /* This portion yields a SINGLE point for each capsule. startKey() generates the point at the START of each capsule, where middleKey() and endKey() could also be used to generate a point at the MIDDLE or END of each capsule. Where these points are placed matter, as that is the point in time the count will increase. */ $samplePerCapsule = $condition.toSignal(startKey()) /* This portion yields the running count of each sample (capsule). The 15d in toStep() can be adjusted. Ideally this number will be the duration of the longest expected time between two events that are being counted. */ $samplePerCapsule.runningCount($manualCondition).toStep(15d) .toStep(15d) ensures the output signal is step interpolated, interpolating points at most 15 days apart. If step interpolation is not required, then this can be removed or replaced with something like .toLinear(15d). Below shows the associated output. Content Verified DEC2023
  22. I have a piece of equipment that regularly goes through cycles and I want to compare the cycles. In this case I know the exact date and time of the equipment runs so I have used the Custom Condition tool to specify my Previous Run and Current Run. Custom Condition allows you to enter dates for the condition you are interested in. This can also be done in formula. To create the condition for my Next Run I used Seeq's formula because this run is currently on going and I do not know the end date. This approach allows me to specify that this condition end at now. condition(2d, capsule('2020-06-01T17:48Z', now())) Now that I have defined my Previous, Current and Next runs I want to calculate the run time of each of those periods. I can do this in Seeq's formula tool using the time since function. This will allow me to create a signal whose value is the time since the start time of a condition. This signal will end at the end of the condition. In this case my time counter will be in hours, if you wanted it in days instead you would change the 1h to 1d. timeSince($condition, 1h) I duplicated this formula three times for my previous, current and next runs. Remember, you can always duplicate a formula by clicking the "i" by item properties. You can compare the run lengths of the 3 runs by putting them on the same lane and same axis. You'll noticed my Next Run has just started so the time since for it is much smaller. Lastly, you can switch to capsule time view to compare the run length as well as different signals over the run. In this case we are looking at the temperature of each run as well as the run length. You could imagine using this approach to monitor heat transfer coefficients, reactor temperature, reactor conversion, or % sulfur removed.
  23. Question: How do I normalize a signal in Seeq? Sometimes it can be helpful to view data on a normalized scale or used normalized inputs in a model. Solution: This solution is posted using R22.0.47 but is applicable to earlier versions. Slight modifications of the formula may be required for earlier versions. 1. Let's start by loading our signal... 2. Next we'll use Formula to create a normalized signal. In Formula we do the following steps Define the time period over which we will do the normalization Calculate the min and max values which occur during that time period Calculate the delta between the min and max Finally, calculate the normalized signal Here is the code snippet if you'd like to copy and paste... $timePeriod = capsule('2019-01-01T00:00-05:00', '2020-01-01T00:00-05:00') $max = $signal.maxValue($timePeriod) $min = $signal.minValue($timePeriod) $delta = $max - $min ($signal - $min) / $delta 3. View the results in Seeq. Note that I optionally created scalar boundaries at 0 and 1 to highlight the normalization of my signal...
  24. Hello Everyone, I hope you are doing well. I need some help with creating a function. I have multiple conditions that I have created that tell me if the equipment is stopped, lag, standby, or other attributes. I want to be able to be able to: ADD Durations for when equipment is stopped and in lag OR when the equipment is stopped or standby. ADD Durations for when equipment is stopped but not in lag or standby. The example variables are in hours. Stopped ($i5) Standby($i6) Lag ($i) I would appreciate the help.
  25. Recently an interesting question came up about converting a number to binary within Seeq. The goal was to convert an integer (0-255) to an 8-bit binary number. This can be done by dividing the integer by 2, 8 times and keeping track of the remainders. More information about binary numbers can be found here. https://en.wikipedia.org/wiki/Binary_number Note: For this conversion to work the input signal needs to be an integer between 0 and 255, also it cannot have units. Below is the formula syntax that will do the conversion. $i=$signal.ceiling().setUnits('') $div1=($i/2).floor() $div2=($div1/2).floor() $div3=($div2/2).floor() $div4=($div3/2).floor() $div5=($div4/2).floor() $div6=($div5/2).floor() $div7=($div6/2).floor() $div8=($div7/2).floor() $rem1=($i/2-$div1).ceiling().toString() $rem2=($div1/2-$div2).ceiling().toString() $rem3=($div2/2-$div3).ceiling().toString() $rem4=($div3/2-$div4).ceiling().toString() $rem5=($div4/2-$div5).ceiling().toString() $rem6=($div5/2-$div6).ceiling().toString() $rem7=($div6/2-$div7).ceiling().toString() $rem8=($div7/2-$div8).ceiling().toString() $rem8+$rem7+$rem6+$rem5+$rem4+$rem3+$rem2+$rem1 Below is a screenshot of the syntax in the formula tool. Result:
×
×
  • Create New...