PRODUCTS

RECIPES COOKBOOK

# 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
}
```
 Content, and web design © 2012-2019 GeolOil LLC. You are welcome to refer them. Please give us fair credits.