Skip to main content

Case Study

Rendering the Client's Own Data Through Covid: The DLIS-to-Pad-Image Pipeline That Opened the Door

The pre-sales story is that the first proposal demo was the client's own data. The engineering story is what made that possible: a working DLIS reader and pad-image renderer, run on the operator's own well within days of a data drop, that pulled one raw frame of 697,502 depth samples across 19 channels, mapped the tool's sentinels to NaN, thresholded at 245, ran Canny(100,255) and Hough, and rendered an eight-pad FMI strip. The archive keeps the honest early-code artifact, a preserved NoneType crash when Hough found no lines, and the earliest renders it produced, folder-dated March 2020.

Quamer Nasimby Quamer Nasim
Case study

The sales version of this engagement has been told already: the first proposal demo to a major operator in Oman was not a generic capability deck, it was the operator's own borehole rendered on our stack, and the earliest surviving render is folder-dated March 2020, well over a year before the contract that paid for the work. That argument, why showing a client a picture of their own rock changes the sale, is made in full in the companion piece on the pre-sales data work, and I will not re-derive it here. This piece is about the thing under that argument. Before there was a demo worth showing, someone had to write the reader that turned the operator's binary log files into an image. I did. This is what that code actually did to their bytes.

The artifact, not the pitch

A DLIS file is not a spreadsheet you open. It is the binary container the wireline industry writes borehole data into, and getting an image out of it means walking its internal structure, finding the right channels, and reconstructing the pixel array by hand. The concrete artifact that de-risked the whole engagement was a notebook that did exactly that, and the archive still holds a run of it against a newly received well, exported and dated early in the programme's data phase. That run is the clearest evidence I have that the ingestion was real and not a promise: it was pointed at a fresh well within days of the data arriving.

When the reader loaded that well's frame, it walked 19 channels: the depth channel, the static image, the four pad channels and four flap channels that carry the microresistivity buttons, plus calipers, gamma, and azimuth. One frame of that log carried 697,502 depth samples. That is the raw material of a single image before any of it means anything, and it is worth sitting with the number, because a reader that chokes on the size or the channel layout of a real operator's file never produces a demo at all.

What the reader did to the bytes

The steps were not exotic, and that is the point. The value was that they ran, in order, on real data.

First, the sentinel. The imaging tool writes a fixed value of -9999 into every pixel it did not measure, which on borehole images is most of the inter-pad wall. Left in place, that -9999 is a valid float that quietly wrecks everything downstream, so the reader mapped it to NaN and dropped the whitespace-gap columns before anything else touched the array. Then a grayscale inversion, so the thresholding read the way the physics did.

Then the classical computer-vision pass that everyone in borehole imaging starts from. Five OpenCV threshold variants at a single cutoff of 245, compared side by side, because on a real log you do not know in advance which one separates sinusoid pixels from background. A median blur to knock down speckle. Canny edge detection at (100, 255) with a wide aperture. Then a probabilistic Hough transform, tuned tight, to pick straight segments out of the edges and turn them into the dip and azimuth of a plane cutting the borehole. If any of this sounds like the industry-standard first move, it is; the same Hough-and-Canny lineage traces back to a Schlumberger patent from the late 1990s, and we started where the field started before earning the right to leave it.

DLIS READER + PAD-IMAGE RENDERER · BUILT ON THE OPERATOR'S OWN DATAMar 2020client data, vendor stack, no contractThe de-risking artifact was a working reader run on the client's own wellTrace it left to right: one raw frame in, a rendered pad strip out, all on our stack.01697,502 samplesone DLIS frame, 19 channels walked02-9999 -> NaNsentinel mapped, gap columns dropped03threshold 245five cv2 variants at one cutoff04Canny(100,255)medianBlur(5), aperture 705prob. Houghthreshold 30, minLen 30, gap 5RENDERED PAD STRIP8-pad FMI · dynamicDEPTH AXIS (FT)8,4008,7759,1509,5259,900earliest archivedrender, folder-datedMarch 2020STAGE 05 OUTCOME ON THIS SECTIONHoughLinesP -> None -> TypeError: len(None)the preserved crash from real early code, not a mockupclick toswitch runone frame in, a client-data pad strip out, on our stack, before any contract existed
A left-to-right trace of the pre-contract ingestion artifact: a working DLIS reader and pad-image renderer run on the operator's own well data. The single raw frame carried 697,502 depth samples across 19 channels; the reader mapped the -9999 sentinel to NaN, dropped whitespace-gap columns, thresholded at a cutoff of 245, ran Canny(100,255), then probabilistic Hough. The trace terminates in a rendered eight-pad FMI strip whose depth axis reads roughly 8,400 to 9,900 feet, folder-dated March 2020, the earliest artifact in the archive. The orange terminal panel is the only element that argues: the client's own data drawn on the vendor's stack before a contract existed. Toggle the stage-05 outcome to see the honest preserved crash, where Hough returned zero lines and the early code fell over with a NoneType error, versus the run where a sinusoid was caught. Sourced: the 697,502 samples, 19 channels, threshold 245, the Canny(100,255) variant, the preserved NoneType crash, and the March-2020 depth axis. Illustrative: the stage ordering as drawn and the banding inside the render strip, which stand for the pad image rather than reproducing it.

The instrument above traces that path left to right, one raw frame in and a rendered pad strip out, and it terminates in the only element that carries the argument: the client's own data drawn on our stack, in orange, before a contract existed. The math the Hough fit is chasing is the sinusoid a planar feature makes when you unroll the cylinder of the borehole into a flat image, which is just

Asin(θ+ϕ)+c,θ[0,360]A \sin(\theta + \phi) + c,\quad \theta \in [0^\circ,\, 360^\circ]

with amplitude set by the feature's dip, phase by its azimuth, and offset by its depth. Fitting that curve is the whole job of the classical stage. What the downstream detector eventually did with those picks, and why a transformer beat the classical fit, is the subject of other pieces in this series; here the fit is the finish line, because a fit means an image, and an image means a demo.

The crash I did not delete

The most honest thing in that archived run is that it does not end cleanly. On the section it was pointed at, the Hough transform found no lines at all. It returned None. The next line of code asked for the length of that None, and Python did what Python does: a TypeError, right there in the exported notebook, preserved.

I could have caught it. It would have been one guard clause. I left it, and I am glad the archive kept it, because it is the truest possible record of what early ingestion code on real operator data looks like. It is not a polished mockup where every section obligingly yields three clean sinusoids. It is a reader breaking on a hard section of a real carbonate well, months before we pivoted to a supervised model that could read the sections classical CV could not. Toggle the stage-05 control in the instrument and you can switch between the run that caught a sinusoid and the run that fell over. Both are real. The one that fell over is the one that tells you the demo was built on real data and not on a curated example, because curated examples do not throw.

Why the earliest render is the receipt

The oldest thing this pipeline produced that still survives is a set of eight raw FMI strip renders in a folder dated March 2020. The depth axis on the first of them runs from roughly 8,400 to 9,900, and the giveaway is the unit: it is in feet, where every later plot in the programme is metric. That single detail dates the artifact to the very start, before the metric conventions of the paid programme had settled. It is an eight-pad Formation Micro-Imager image, orange colormap, bedding banding across the pads, the characteristic wedge gaps where the tool measured nothing and the sentinel had to be mapped out.

Nobody was paid to make those renders. There was no scope schedule, no milestone tranche, no line item. They exist because the reader ran, through Covid, on the operator's own DLIS drop, and someone wanted to see whether the carbonate had structure worth building a detector for. The March-2020 folder is the receipt for that: not a claim that the ingestion would work on their data, but proof that it already had.

Why this is the milestone that mattered

It is tempting to treat ingestion as plumbing, the unglamorous layer you get past on the way to the model. On this engagement the plumbing was the milestone. The reader that mapped the sentinel, walked the 19 channels, chewed through 697,502 samples without choking, and rendered a clean pad strip is the concrete thing that turned a speculative conversation into a demo of the client's own rock. Every model that came later, every ablation and every metric, sits on top of an image, and the image sits on top of that reader. De-risking an enterprise AI engagement is often assumed to be a matter of proposals and references. Here it was a working DLIS parser, run on the operator's own well, that made the first meeting a demonstration instead of a promise.

Limitations

This is one engagement and one archived run, read from an exported notebook and folder timestamps, not from a reconstructed engineering log. The 697,502-sample count and the 19-channel walk are from that single frame; other wells and other frames differ, and the number is a real reading, not a benchmark. The threshold cutoff of 245, the Canny (100, 255) parameters, and the Hough settings are the values in that notebook, chosen for that data, not general recommendations. The preserved NoneType crash is a real artifact of early code on one hard section and should be read as honesty about the state of the ingestion at that date, not as a claim that classical CV fails everywhere. The March-2020 renders are the earliest surviving artifacts, which places the pre-contract technical work at that date but does not prove it began exactly then. The commercial argument that this artifact won the programme is made, and caveated, in the companion pre-sales piece; treat this account as the engineering record behind that argument, not as evidence that unpaid speculative work is the right strategy in general.

References

  1. Ingestion notebook run on the operator's own well data, exported early in the programme's data phase: a DLIS load and channel walk over 19 channels, 697,502 depth samples in the single frame, -9999 sentinel mapped to NaN with whitespace-gap columns dropped, five OpenCV threshold variants at a cutoff of 245, median blur, Canny(100, 255) with a wide aperture, and a probabilistic Hough transform, ending in a preserved NoneType error where Hough returned zero lines. Internal materials, withheld under operator confidentiality.

  2. Earliest data folder in the engagement archive: eight raw FMI strip renders folder-dated March 2020, the first covering roughly 8,400 to 9,900 feet on a depth axis in feet, rendered from the operator's DLIS files. Internal materials, withheld under operator confidentiality.

Go to Top

© 2026 Copyright. Earthscan