Have you ever been frustrated when you tried to:
- Compare two file fields
- Display every 10th record from a large file
- Combine separate red, green, and blue values into a colour that Micromine can display
- Perform a calculation that needs the value from the previous or next record
- Construct a complicated label from multiple fields?
Although these tasks are all relatively simple they require temporary fields to get the job done, forcing you to modify the file. This can be a problem if you don’t have the necessary permissions or if the file needs to stay in a standard format. In Micromine 2016 you can do the job much more simply and on-the-fly by creating a dynamic field expression.
Field expressions are like equations that define a relationship between one or more file fields, constants, functions and operators. You can use expressions anywhere you’d supply an input fieldname, which means they work in filters, colour sets, labels and calculations, all without altering the input file.
Here’s an example:
This simple expression calculates the difference between fields called K2O and NA2O. The equals sign (=) tells Micromine that this is an expression instead of a regular file field, and the square brackets indicate each fieldname.
The square brackets aren’t compulsory but they do make it easier to identify fieldnames in a complex expression. However, they become compulsory if your fieldnames include spaces or reserved characters like ‘+’ or ‘/’.
You can use this expression in pretty much any input field response, such as a Colour field. The best part when you assign values to a colour set based on this expression is that you get numbers that span the full range of differences between the fields, not their original values.
What if you simply want to show if K2O is greater than NA2O? Easy:
=[K2O] > [NA2O]
This is an example of a logical comparison that returns true (1) when K2O is greater than NA2O, and false (0) when it is not. A corresponding (assigned) colour set runs from zero to one (I manually relabelled the two colours in the screenshot).
So far I’ve only looked at numbers, but what about if you want to label the result? Try this:
=if([K2O] > [NA2O]) then "Potassic" else "Sodic" endif
This is a classical if-then-else statement. If K2O is greater than NA2O the text will be “Potassic”, otherwise it will be “Sodic”. You must always include the endif statement. (You can also use fi – as in finished.)
Using the preceding expression as a Text Field in a Vizex Point layer will display the labels “Potassic” or “Sodic” at each point regardless of the original numerical values.
You can optionally use the pound/hash symbol (#) to tell Micromine to convert numerical values to text. Although the # isn’t compulsory, it’s a good idea to include it whenever you want to guarantee text output. This is especially true when you’re combining numbers and text, because the ‘+’ operator concatenates text strings whenever you “add” them. For example:
=3 + 4
produces the number 7, whereas
=#(3 + 4)
produces the text “7”, and
=#3 + 4
produces the text “34”, which is simply the concatenation of 3 and 4.
This powerful feature makes it easy to create complex labels by combining any number of separate file fields, but it’s easy to become confused if some of those fields contain numbers. For example, when looking at a printed map, how would you know if the label “7” or the label “34” was correct?
A simple rule of thumb for using the # is to keep its scope as small as possible, by only applying it to numbers or numerical expressions you want to format as text.
You can really go to town with expression-based labelling, from really basic labels like:
="Area = " + #[AREA] + " sq m"
(note the space after the = and before the sq m)
=if([NA2O] > 0) then "K:Na ratio=" + " " + #([K2O] / [NA2O]) else "" endif
This expression combines a bunch of different elements to display the K/Na ratio of the input data. To avoid division by zero the label is conditionally applied where [NA2O] > 0. For non-zero values the label is then constructed from three separate parts: the "K:Na ratio=" prefix, concatenated with an extra space + " " , concatenated with the calculated ratio [K2O] / [NA2O]. For records where NA2O is zero the else statement sets the label to nothing (the empty double quotes "").
Disclaimer: although you can use expressions in most text/label field responses there are still some places in this Beta that don’t support expression labelling.
If you’re wondering how to edit a complex multi-line expression in a (relatively) small field response, simply right-click it and choose Edit Expression from the pop-up menu. Micromine will display a formatted version of the expression with the = already included. The expression editor also lists the Available Fields and Available Functions, from which you can quickly build an expression by double-clicking fields and functions as required. For now you still have to manually enter everything else.
Clicking the Check button gives you an opportunity to validate and correct the expression before you use it.
Although it’s perfectly valid to enter a large expression on one line:
=if([K2O] > [NA2O]) then "Potassic" else "Sodic" endif
I think you’ll agree it’s much easier to read on multiple lines.
The same applies to whitespaces. You can build expressions with or without spaces, although using them does make your expressions easier to read. A simple rule of thumb is to add a space wherever necessary to improve clarity.
So far I’ve used expressions in colour fields and text fields, purely because they’re visual and easy to understand. But you can use expressions anywhere you’d use an input file field, and two obvious places are in a filter and in the calculator.
To reproduce the [K2O] > [NA2O] expression in a filter:
Please note that a filter is just an if statement; the then is whichever task has the filter applied. Other than reversing the filter there is no equivalent to an else statement.
I mentioned at the beginning of this post that expressions are like equations, and of course they’re easily used as equations. In fact, we’ve made a whole new calculator that only uses expressions, which you can find at File | Fields | Calculate (Expression). This is where expressions really start to fly; instead of setting up a multi-stage calculation using the existing Calculator, simply write the equation as an expression.
Suppose you wanted to convert polar coordinates to rectangular coordinates. In the old Calculator you would do this:
In the new expression-based calculator it looks like this:
As you can see, each expression combines two calculations into one step without resorting to temporary variables, producing a much more succinct solution that is readily understood and easily maintained.
Disclaimer: we’re still working on the underlying expression mathematics and the current function list in this Beta is pretty limited.
As a working example, the limestone industry uses the lime saturation factor (LSF) to determine the characteristics of the raw material. The calculation looks like this:
= 100 * [CAO] / (2.8 * [SIO2] + 1.18 * [AL203] + 0.65 * [FE203])
I’ll leave this as an exercise for you to recreate using the old calculator.
When you’re using Calculate (Expression) you’ll notice that the Available Fields list includes fieldnames with ‘<’ prepended and ‘>’ appended to each name. For example, [EAST] will be accompanied by [<EAST] and [EAST>]. You use the prepended (<) version to obtain that field’s value from the previous record, and the appended (>) version to obtain the field’s value from the next record.
Suppose you wanted to measure the differences between successive records in a non-drillhole file:
Now that was easy, wasn’t it?
Everyone seems to be acquiring LiDAR data nowadays, and many surveys produce point clouds where each point has R,G,B attributes in addition to the standard X,Y,Z values. In other words each point knows its colour.
A vexing problem of dealing with this data is to generate colour from a file that has separate red, green and blue value fields. Micromine 2014 introduced the ability to automatically display colour directly from a colour field, but its biggest limitation was that you had to manually convert the RGB triplets into a number Micromine could understand.
Nowadays you can simply use the RGB() function, like this:
where [R], [G], and [B] are the red, green and blue fieldnames.
My final example is to display, label, or modify every nth record. This method that pretty much requires you to modify the input file, but it’s still far more efficient to use an expression to make the change.
A typical every nth scenario is to create contours from a DTM or grid surface and then label every nth contour as Index, with the remainder labelled as Intermediate. Suppose you generated two-metre contours and wanted multiples of 10 to be Index contours:
=if([ELEV] % 10) = 0 then "Index" else "Intermediate" endif
The % (modulo or modulus) operator calculates the remainder after division. For example, 12 % 10 is 2. At school you might have said it as “12 divided by 10 is 1, with remainder 2”. Similarly, 20 % 10 is zero because there is no remainder.
In the contouring example, elevations that are multiples of 10 have zero remainder and are labelled as Index contours. Everything else has a non-zero remainder and is labelled as Intermediate. You can use this expression to create labels on-the-fly, or use it in Calculate (Expression) to produce a permanent label field.
Another every nth scenario is to simplify a calculation by only using every nth record. Here you must modify the file because this method relies on a record ID (RID) field, which is simply an incremental value that reproduces the row labels at left of the File Editor. To use every 25th record in a calculation or for labelling:
=if ([RID] % 25) = 0 then "Label this" else "" endif
I hope this introduction to expressions in Micromine 2016 Beta whets your appetite to experiment with them on your data, remembering that we’re still finalising the feature list and some minor things may change. Having said that, we’re pretty excited about the potential that expressions offer.
Customer support service by UserEcho