PS. Code Filters
A Code Filter is an additional piece of logic evaluated during the Destination Rule selection process. This filter is designed to evaluate a simple logic statement that returns “True” or “False”.
Within Production Scheduler, Code filters can be added through scripts, as well as through the Destination Rules Step.
In most situations, Code Filters created in the Destinations Rules step should suffice; however, if the logic to be evaluated is quite complex or there are many Code Filters required, it may require the Code Filters to be created through scripts.
Launching the Code Editor
Creating Code Filters
In the Destinations Rules Step click the Codes Filters button.
The Block Filter Code Editor dialog will appear, where you can add a new code filter and manage with it as described below.
Code Filter Toolbar items
Button | Description |
---|---|
Add a new Code Filter | |
Remove selected Code Filter | |
Move selected Code Filter Up or Down in the list | |
Load in Code Filter from file | |
Save selected Code Filter | |
Save all Code Filters within the project |
Code Editor panel
The Code Editor panel is where the Code Filters are written. It comprises a toolbar, text editor, and two helper tabs (Formulas and Errors) located down the bottom.
Toolbar
Button | Description |
---|---|
Compiles the code. If any errors are present, errors will be displayed in the Errors tab located at the bottom of the editor. | |
Undo <CTRL + Z> or Redo <CTRL + Y> previous actions |
Text Editor
The text editor is where the code for the filters is written.
Formulas tab
The Formulas tab contains a list of helper functions that can be used to help construct Code Filters. They are designed to provide a high level of abstraction to the user and make creating Code Filters easier by reducing the amount of code needed to be written.
Formulas | Description |
---|---|
Generate CalendarInput | Used to generate the code required for creating a new Custom Calendar Input |
Create <Activity> Double Field Reference | Used to create the code required to create a double Field Reference for the chosen Activity (Blast Solid, Dig Solid, Mining, Production Drilling etc.) |
Create <Activity> String Field Reference | Used to create the code required to create a string Field Reference for the chosen Activity (Blast Solid, Dig Solid) |
Only Activities that have been enabled within the project will be displayed here. This list will vary from project to project.
Errors Tab
The Errors tab will show any errors which were encountered during the compilation of the Code Filters. Errors will be listed one by one, and the line where the error occurred will also be shown alongside the error.
Use Case
To help better understand the use of Code Filters, the following use case is presented.
“Stockpile SP1 can accept HG parcels; however, it can only accept HG parcels if the Fe is above 61% and if SiO2 is below 3.”
Without Code Filters, this kind of logic is difficult to manage. A possible solution would be to go back to Rapid Reserver and create a new HG parcel with Fe above 61 and SiO2 less than 3. This solution is not very flexible as if the cut off values change, we would be required to go back to Rapid Reserver and regenerate our parcels. Code Filters allow user to model this type of situation easily and can be managed without regenerating reserves.
Step 1 - Create Code Filter
Using the Code Filter Toolbar, create a new filter and give it a name.
Step 2 - Define required variables
The sole objective of this Code Filter is to determine whether the Fe and SiO2 of mined HG blocks fall within the given cut off values. To achieve this, we need to create variables to store the address of the Fe and SiO2 fields so we can retrieve the values. We also need to create two variables to store the calendar inputs so we can enter the cut-off values.
Variable Type | Description |
---|---|
IProductionDoubleReference | Stores a reference to a particular Database field |
CustomCalendarInput | Stores the Custom Calendar Input which is displayed in the Scheduling Calendar |
Step 3 - Create Calendar Inputs
In the previous step, we defined two CustomCalendarInput variables. We now need to assign values to those variables, and this done in the CreateCalendarInputs method. The easiest way to achieve this is outlined below.
Within the CreateCalendarInputs method, grab a variable “_feCutOff” and place an assignment operator (=) on the right-hand side.
Select and double click on the Generate CalendarInput formula from the Available Formulas list.
3. Fill out the required inputs and once completed, press OK.
Configure Generate CalendarInput dialog items
Name | Description |
---|---|
Names | Name structure for additional calendar field. Names will be nested under one another |
Default Value | The default value shown in the calendar field when new periods are created |
Minimum Value | The minimum value allowed to be entered into the field by the user |
Maximum Value | The maximum value allowed to be entered into the field by the user |
Display Format | The format in which data is displayed in the calendar |
4. Review the code which was inserted and edit it, if required.
5. The additional Calendar Fields will appear in the Calendar tab. The values can be updated by period, which is handy if the values change from period to period.
Step 4 - Create Field References
In the Step 2, we declared two variables that were intended to store the address of the Fe and the SiO2 database fields. Just like the Custom Calendar variables, we need to assign values to these variables. The easiest way to achieve this is outlined below.
Within the CreateFieldRefernce method, grab a reference variable “_feGrade” and place an assignment operator (=) on the right-hand side.
Select and double click on the Create Mining Double Field Reference formula from the Available Formulas list.
3. Select the relevant field from the dropdown list and press OK.
4. Review the code which was inserted and edit it, if required.
Step 5 - Define the logic expression
The result of a Code Filter is either “True” or “False”. The logic that determines this outcome is defined in the Include method. In the Include method, user automatically gets past a mining block from the schedule designated by the variable 'b'.
In the use case example, we want to determine if the Fe value of the block is greater than the Fe cut-off value and if the SiO2 value is less than the silica cut off. This can be achieved by the following.
Grab the Fe value of the block using the “_feGrade” variable and the variable “b” (scheduling block).
Grab the user-defined cut-off value from the calendar using the “_feCutOff” variable.
Use a boolean expression to check if the Fe value is greater than the cut-off value.
Store the result of the boolean expression in a local variable.
Repeat steps 1-4 for SiO2.
Use a boolean expression on resultant variables created in the Step 4.
Step 6 - Applying the Code Filter
Once the Code Filter has successfully been compiled, it can be accessed by picking it from the Code Filter dropdown on the relevant destination rule. In the example shown below, any Ore mined from the pit that satisfies the code filter logical condition, Fe >= X and SiO2 <= Y, will be sent to Stockpiles/SP1. If the logical expression fails, the next destination rule will be assessed, meaning Ore will be sent to Stockpiles/SP2.
Fully Worked Example
using System;
using Alastri.Patri.V2;
using Alastri.TotalScheduler.ScriptExtensions;
using Alastri.TotalScheduler.ScriptExtensions.Modifiers;
using System.Collections.Generic;
using Alastri.Scripting;
using Alastri.SchedulingCore;
public class SimpleProductionBlockFilterSample : SimpleProductionBlockFilter
{
//Variables to store the database adress of the grade fields
private IProductionDoubleReference _feGrade;
private IProductionDoubleReference _siO2Grade;
//Variables to store the additional calendar input
private CustomCalendarInput _feCutOff;
private CustomCalendarInput _siO2CutOff;
public override void CreateCalendarInputs(CalendarInputContext context)
{
_feCutOff = context.CreateCalendarInput(new InputTemplate
{
Names = new string[]{"Code Filters", "Fe SiO2", "Fe"},
DefaultValue = -1,
MinValue = -1,
MaxValue = 100,
Format = "#,##0.00",
});
_siO2CutOff = context.CreateCalendarInput(new InputTemplate
{
Names = new string[]{"Code Filters", "Fe SiO2", "SiO2"},
DefaultValue = -1,
MinValue = -1,
MaxValue = 100,
Format = "#,##0.00",
});
}
public override void CreateFieldReferences(FieldReferenceContext context)
{
_feGrade = context.GetMiningDoubleReference("grades_Fe");
_siO2Grade = context.GetMiningDoubleReference("grades_Sio2");
}
public override bool Include(IProductionSchedulingBlock b)
{
double feValue = _feGrade.GetValue(b); //Get the Fe value from the block
double feCutOffValue = _feCutOff.Value; //Get the cut-off value from the calendar
bool fePass = feValue >= feCutOffValue; //Compare the two values
double siO2Value = _siO2Grade.GetValue(b); //Get the SiO2 value from the block
double siO2CutOffValue = _siO2CutOff.Value; //Get the cut-off value from the calendar
bool siO2Pass = siO2Value <= siO2CutOffValue; //Compare the two values
//Returns True if both fePass and siO2Pass are True, else it returns False
return fePass & siO2Pass;
}
}