GeolOil - GLS Well Logging Scripting Programming Language
How many times have you needed to create or modify a log curve, using your
equations and algorithms, only to discover that other petrophysical
software offer limited choices?
How many times have you ended using Excel spreadsheets, or Python script routines?
GLS GeolOil Logging Scripting is perhaps the easiest tool
to write your own simple and short source code.
Type your own equations, calibrations, variable petrophysical
parameters per zone in a curve, or design your own functions and algorithms
quickly. For example, the classical Archie SW water saturation
to enforce its result to 0-1 can be scripted as:
phi = @13; rt = @7; rw = @10
a = 0.81; m = 1.9; n = 1.8
F = a/(phi^m); SW = (F*rw/rt)^(1/n)
SW = trim (0, SW, 1)
where porosity is the LAS curve number 13, deep or true resistivity the curve 7, and formation
water resistivity the curve 10. No worries about missed -999.25 values in any curves.
GeolOil will analize, compile and run your code behind the scenes
(check the GLS Reference Manual for details).
You can also of course compute SW easily with our collection of 24 built-in, out of the box GUI water saturation models.
Let's suppose now that you are processing a large depth interval. A clean eolian sandstone formation
A spans from MD=3507-4713, and a carbonate formation B spans from MD=4713-6876.
The electrical parameters for the clastic formation are a=0.81, m=1.9, n=1.8.
But the parameters for the carbonate zone are different, a=1.0, m=2.0, n=2.0.
One easy solution to compute SW, is to define a, m, n, not as constants, but curves. This is how:
MD = @1; phi = @13; rt = @7; rw = @10
topA = 3507; baseA = 4713
topB = baseA; baseB = 6876
indicatorZoneA = ind (topA, MD, baseA); indicatorZoneB = ind (topB, MD, baseB)
aCurve = 0.81 * indicatorZoneA + 1.0 * indicatorZoneB
mCurve = 1.9 * indicatorZoneA + 2.0 * indicatorZoneB
nCurve = 1.8 * indicatorZoneA + 2.0 * indicatorZoneB
F = aCurve/(phi^mCurve); SW = (F*rw/rt)^(1/nCurve); SW = trim (0, SW, 1)
SW = SW * blankOutside (topA, MD, baseB) # Interpreted 3507-6876. Set -999.25 outside
Notice how this concise and legible code does not require special syntax like for, if, then, else:
It is a Stream Scripting language. It analyzes, compiles and executes the necessary
loops and if conditions to skip -999.25 occasional curve values. That simple, yet powerful.
The figure below shows the GLS script window, integrated in the Functions panel:
GLS is a minimal, domain specific scripting language
to process well logs for petrophysicists and geologists.
It has two modes, the Stream Scripting already shown is the simpliest one
(most problems are solved with this mode), and the GLS conventional
Regular Scripting that might be preferred by users with basic programming skills
using if, then, else, and for depth looping syntax. Both modes can be integrated seamlessly.
Just to explore how GLS Regular Scripting can be blended with GLS Stream Scripting,
check an equivalent example code using a depth loop:
MD = @1; phi = @13; rt = @7; rw = @10 # Curve algebra is inhereted automatically
topA = 3507; baseA = 4713
topB = baseA; baseB = 6876
indicatorZoneA = ind (topA, MD, baseA); indicatorZoneB = ind (topB, MD, baseB)
aCurve = 0.81 * indicatorZoneA + 1.0 * indicatorZoneB
mCurve = 1.9 * indicatorZoneA + 2.0 * indicatorZoneB
nCurve = 1.8 * indicatorZoneA + 2.0 * indicatorZoneB
SW = new LasCurve (MD.blank()) # Entering Reg. Script. mode: defines a -999.25 curve explicitly
steps = MD.size();
for (int depthIndex=0; depthIndex < steps; ++depthIndex)
{
por = phi.get (depthIndex) # Don't worry about -999.25. GLS will handle those.
res = rt.get (depthIndex)
rwt = rw.get (depthIndex)
a = aCurve.get (depthIndex)
m = mCurve.get (depthIndex)
n = nCurve.get (depthIndex)
F = a/(por^m); swValue = (F*rwt/res)^(1/n);
if (!isValid(swValue)) {continue;} # Any comparison < or > with invalid numbers must be skipped
if (swValue < 0) {swValue = 0.0;} # Although this should not happen, put better a SWirr value
if (swValue > 1) {swValue = 1.0;}
# Note: all not valids swValue skipped, keep their default -999.25 initial values
SW.set (depthIndex, swValue)
}
# compare if, else instructions with stream command: SW = trim (0, SW, 1)
# Back to simpler Stream curve mode
SW = SW * blankOutside (topA, MD, baseB) # Interpreted 3507-6876. Set -999.25 outside
return (SW) # This command is optional, but recommended.
Notice that the regular scripting code is far longer and complex than its stream script version. More important,
the GLS Stream Scripting language is safer, readable, and will take care of most details, logic, looping,
and skipping special cases for you. Just design and type your equations as you think them.
The GLS Stream Scripting properly takes care of invalid numbers and -999.25 exceptions. But if you prefer or need
maximum control and use the GLS regular scripting, it is advised to skip all invalid cases explicitly.
Although any operation involving -999.25 or invalid numbers will produce -999.25 results,
comparisons like == or < or > will behave unexpectedly and must be avoided manually.
The best way to skip invalid numbers in the depth for loop is then:
for (int depthIndex=0; depthIndex < steps; ++depthIndex)
{
por = phi.get (depthIndex) # Don't worry about -999.25. GLS will handle those.
res = rt.get (depthIndex)
rwt = rw.get (depthIndex)
a = aCurve.get (depthIndex)
m = mCurve.get (depthIndex)
n = nCurve.get (depthIndex)
if ( (!isValid(por)) || (!isValid(res)) || (!isValid(rwt)) || (!isValid(a)) || (!isValid(m)) || (!isValid(n)) )
{continue;} # Continue cleanly skips to the next for depthIndex iteration. No worries using comparisons.
... etc. More code as before
}
|
Related article:
|
|
Related video:
|
|