Exercises: Expression Builder Walkthrough

This walkthrough will use an Expression to calculate drill and blast fields.

Rapid Reserver Setup

For this model two blast properties were added to Rapid Reserver:

  • Initial State – Used to set the initial state of a blast.

  • Contour Percent – Used to calculate drilling for patterns that have areas for both production and contour drills.

In the Designer, values were populated on different blasts for testing and validation purposes:

APS – Settings

Tick on ‘Use Expression Builder’:

APS – Production Mode Features

For the walkthrough, tick on drilling, charging and the generic activity that occurs before drilling:

APS – Parcels

For this walkthrough, parcels have been setup as follows:

Activity

Parcel

Comment

PreDrilling

PatternPrep

Generic name to represent area required for pattern preparation.

ProductionDrilling

251, 165

Values represent the drill bit diameter used for production and contour drilling.

ProductionCharging

ANFO, Mix8020, Mix6040, Emulsion

Different explosive types. 

Mining

Variable

These will be unique to each model and will not impact the expressions being created during the walkthough.

APS – Fields

Additional fields are required to be added to hold final values as well as assisting in calculations. Having extra fields for temporary calculation steps will help in validating that Expressions are working as intended.

Note: Field collections not mentioned below, are not used in Expressions through the walkthrough.

BlastSolid

Add two new fields to hold the Blast Properties from Rapid Reserver:

PreDrilling

Add field to be used as Primary field for PreDrilling activity:

ProductionDrilling

For Production Drilling in addition to holes and meters, 2 temporary fields are going to be added to help with calculations, tempHoles251 & tempHoles165.

Why have tempHoles? This is to avoid recalculating the number of holes for charging requirements. If the initial state is drilled, then number of holes would be set to zero.

Why separate by parcel when the software already does this? Once again this was done to simplify the charging requirements as the diameter is required to calculate explosives tonnes.

ProductionCharging

For Production Charging in addition to design charge, 1 temporary field is added to simplify calculations.

Why have chargeLength? Having this field helps simplify the design charge calculation. This can be used to validate scenarios where the average pattern depth is less than the minimum charge length.

Primary Fields

Choose the appropriate field for each activity:

Map Data

Map the blast properties from the Rapid Reserver to the BlastSolid fields:

Database Inputs – Table Setup

To help create long lists of inputs it is recommended to use iteration lists. These will create multiple inputs for each item in the iteration list.

Row Type

Indent

Full Name

Name

Input Type

Iteration List

Comments

Title

0

(Auto)

BlastType

N/A

N/A

 

Iter

1

(Auto)

N/A

N/A

BlastSolid.BlastType

For each BlastType in the model, create rows for each child row.

Value

2

(Auto)

Diameter

Choice

Parcels – ProductionDrilling

Creates a dropdown option with drill diameters. This allows a diameter to be assigned to each pattern type.

Value

2

(Auto)

Burden

Double

N/A

 

Value

2

(Auto)

Spacing

Double

N/A

 

Value

2

(Auto)

Subdrill

Double

N/A

 

Value

2

(Auto)

Stemming

Double

N/A

 

Title

2

(Auto)

ExplosivePercent

N/A

N/A

 

Iter

3

(Auto)

N/A

N/A

Parcels – ProductionCharging

For each ProductionCharging Parcel, create rows for each child row. 

Value

4

(Auto)

Percentage

Double

 

 

Title

0

(Auto)

Explosive Densities

N/A

N/A

 

Iter

1

(Auto)

N/A

N/A

Parcels – ProductionCharging

For each ProductionCharging Parcel, create rows for each child row. 

Value

2

(Auto)

Density

Double

N/A

 

Note: Using BlastSolid.BlastType as an iteration list creates a relationship between the input field and database. This allows the software to automatically grab the correct input value from the table based on the blastType.

Database Inputs – Table

From the setup above, one can see how the iteration lists are being applied:

Expression Builder

The Expression builder is where mapped fields are combined with data inputs to calculate new database values.

PreDrilling

Only one field should be visible for an expression. If the field is not visible, check that is has been added as a field to PreDrilling and is not mapped under Map Data.

Even though PreDrilling uses area as the primary field, the model needs to consider the initial state of the pattern. This can be done using a simple if statement.

By Parcel

Field Name / Parcel

APS Expression

What it means

No

 

T("BlastSolid.initialState") == "Insitu" ? N("BlastSolid.surfaceArea") : 0

If the Initial State of the Blast Solid is Insitu, then set the value to the Blast Solid area, otherwise set to zero.

 

 

 

If Initial State = Insitu,    Then Surface Area,     Else 0

Since PreDrilling only has one parcel type, there is no need to use ‘By Parcel’ option.

Once that Expression is complete, run one step forward to Expression Refined Database to validate results.

ProductionDrilling

ProductionDrilling has multiple parcels which will require the ‘By Parcel’ Option to be used.

By Parcel

Field Name / Parcel

APS Expression

What it means

Yes

tempHoles251 / 251

RT("BlastType/<BlastSolid.blastType>/Diameter") == Parcel ?

N("BlastSolid.surfaceArea") / (RN("BlastType/<BlastSolid.blastType>/Burden") * RN("BlastType/<BlastSolid.blastType>/Spacing")) * (1 - N("BlastSolid.contourPct")) : 0

 

To make interpreting the above expression easier it has been separated in pieces and explained below.

Section

What it means

RT("BlastType/<BlastSolid.blastType>/Diameter")

Get the Diameter from the inputs table that matches the blast type for the record being evaluated.  

== Parcel

Does the Diameter for the pattern match the parcel being evaluated.   In this case the Parcel is 251.

N("BlastSolid.surfaceArea")

Get Blast Solid Surface Area from the main database.

RN("BlastType/<BlastSolid.blastType>/Burden")

Get the Burden from the inputs table that matches the blast type for the record being evaluated.  

RN("BlastType/<BlastSolid.blastType>/Spacing")

Get the Spacing from the inputs table that matches the blast type for the record being evaluated.  

N("BlastSolid.contourPct"))

Get Blast Solid Contour Percent from the main database.

And when that all gets put together:

By Parcel

Field Name / Parcel

APS Expression

What it means

Yes

tempHoles251 / 251

RT("BlastType/<BlastSolid.blastType>/Diameter") == Parcel ?

 

If the pattern diameter equals 251

N("BlastSolid.surfaceArea") / (RN("BlastType/<BlastSolid.blastType>/Burden") * RN("BlastType/<BlastSolid.blastType>/Spacing")) * (1 - N("BlastSolid.contourPct")) :

 

Then calculate the number of holes and adjust by the contour percent

 

Number of Holes = Surface Area / (Burden * Spacing)

0

Else zero

 

What about parcel 165 under TempHoles251? Since this field will only report 251 holes, parcel 165 can simply be hard coded to 0.

Looking at the expressions in basic text is not great, fortunately the Edit Expression window helps with this. Comments can also be added to the expressions to make them easier to read. Use /* to start a comment and */ to end it.

Repeating the same exercise for tempHoles165. Parcel 251 can be hard coded to 0.

For parcel 165, things may appear a bit more complicated, but this is just an extra check if a pattern contains contours.

By Parcel

Field Name / Parcel

APS Expression

What it means

Yes

tempHoles165 / 165

RT("BlastType/<BlastSolid.blastType>/Diameter") == Parcel ?

If the pattern diameter equals 165

 

 

 

N("BlastSolid.surfaceArea") / (RN("BlastType/<BlastSolid.blastType>/Burden") * RN("BlastType/<BlastSolid.blastType>/Spacing")) :

 

If the diameters match, calculate number for 165 holes

 

 

N("BlastSolid.contourPct") == 0 ? 0 :

If pattern diameters don't match, check if pattern contains contour percent

If contour percent is zero then set value to zero

 

 

(N("BlastSolid.surfaceArea") / (RN("BlastType/Contour/Burden") * RN("BlastType/Contour/Spacing")) * N("BlastSolid.contourPct"))

 

If pattern contour percent exists, then calculate 165 holes usings contour pattern inputs

The last two fields are much simpler as all the hard work has been done.

Since tempHoles are already split by diameters, there is no need to calculate holes by parcel. All that needs to be done is to check the initial status and add the temp holes together.

By Parcel

Field Name / Parcel

APS Expression

What it means

No

Holes

T("BlastSolid.initialState") == "Blasted" || T("BlastSolid.initialState") == "Drilled" ? 0 :

 

If the initial state is Blasted or Drilled then set value to zero

 

 

N("ProductionDrilling.tempHoles251",Parcel) + N("ProductionDrilling.tempHoles165",Parcel)

 

Else add the value from tempHoles from both fields where the parcels match.

Remember that expressions are always evaluated at the parcel level, so using N("ProductionDrilling.tempHoles251",Parcel) will get the number of tempHoles251 which match the parcel being evaluated. When evaluating parcel 251, the expression above becomes tempHoles251 + 0. Similarly, when evaluating parcel 165, the expression above becomes 0 + tempHoles165.

The final drilling field to calculate is meters. In this walkthrough, it is assumed that all pattern types will use the same calculation for hole depth, so there is no need to calculate by parcel.

By Parcel

Field Name / Parcel

APS Expression

What it means

No

Meters

N("ProductionDrilling.holes",Parcel) *

 

Get the number of holes for the associated parcel.

 

 

(N("BlastSolid.volume") / N("BlastSolid.surfaceArea") + RN("BlastType/<BlastSolid.blastType>/Subdrill"))

 

Calculate average bench height and add subdrill for the blast type.

Once all Expressions are complete and valid, run one step forward to Expression Refined Database to validate results.

ProductionCharging

The first field to calculate will be chargeLength. This field is not required, but it does simplify the subsequent expression. Also, if there were other checks for minimum hole depth or charge length, they could be done here.

No need to calculate by parcel since the charge length per hole is assumed to be the same regardless of the explosive type being used.

By Parcel

Field Name / Parcel

APS Expression

What it means

No

chargeLength

T("BlastSolid.initialState") == "Blasted" ? 0 :

 

If the initial state is Blasted then set value to zero

 

 

N("BlastSolid.volume") / N("BlastSolid.surfaceArea") + RN("BlastType/<BlastSolid.blastType>/Subdrill") - RN("BlastType/<BlastSolid.blastType>/Stemming")

 

Calculate average bench height and add subdrill and subtract stemming height.

Charging quantity is essentially calculated in 3 sections:

  • Quantity for 251mm holes

  • Quantity for 165mm holes when the pattern in not a mix of production and contour

  • Quantity for 165mm holes when the pattern is a mix of production and contour

The expression for each will be the same, so only one will be looked at in detail.

In this expression the Parcel name is being added to the expression, this will update the input fields being referenced and remove the need to calculate by parcel.

By Parcel

Field Name / Parcel

APS Expression

What it means

No

designCharge

N("ProductionDrilling.tempHoles251") *

Get the number of 251 holes

 

 

N("ProductionCharging.chargeLength",Parcel) * Pi * Math.Pow(.251/2,2) *

Calculate the volume of explosive required

 

 

RN("ExplosiveDensities/" + Parcel + "/Density") *

Get the explosive density for the parcel being evaluated

 

 

RN("BlastType/<BlastSolid.blastType>/ExplosivePercent/" + Parcel + "/Percentage") / 100

Get the explosive percentage for the blast type and parcel being evaluated

Note: In the above expression, the ‘wildcard’ inputs were combined with the Parcel name formula to add more flexibility to the expression.

When all 3 hole types are calculated, the expression should look something like this:

Quick check in the Expression Refined Database:

Expression Builder