Files
LAS-stream-viewer/README.md
2026-06-02 15:57:44 +05:30

6.5 KiB
Raw Permalink Blame History

LAS Stream Viewer

A drilling-data viewer for very large (10 GB+) LAS well-log files. A Java 21 / Quarkus backend indexes the file in a single streaming pass (constant, tiny memory footprint); a React + Vite UI presents the data three ways:

  • 📈 Log Plot — a multi-track drilling strip-chart / log plot (the way an engineer reads a well).
  • ⊕ Crossplot — WOB-vs-ROP (and any X/Y) drilling-optimization scatter, colored by depth/time.
  • 𝍌 Raw / QC — line-by-line virtualized view with live SSE streaming and whole-file search.

Built for the Pason-style LAS 2.0 logs in Desktop\LAS files (up to ~12.5 GB, ~426 curves, ~2.5 M rows). Nothing in the design assumes the file fits in memory.

Why it scales

Concern Approach
Open a 12.5 GB file Open-in-place (no copy) — or resumable 16 MiB chunked upload
Random line access One-pass sparse byte-offset index (a checkpoint every 256 lines ≈ 80 KB for 2.5 M lines)
Curve plots over millions of samples Pyramid of min/max and mean built per 32-row bucket during the same pass
Honest decimation min/max per pixel, never averaging — a 2 s gas kick or torque spike survives when zoomed out
Indexing memory Single streaming pass, 1 MiB buffer + tiny index + tens-of-MB pyramid — independent of file size
Raw streaming One BufferedReader advanced sequentially; lines pushed over SSE with backpressure
Browser memory Virtualized line list + capped (20 K-line) cache; plots fetch only the visible window, decimated

Drilling features

  • Channel-role resolver maps the ~426 raw Pason mnemonics to drilling roles (ROP, WOB, RPM, torque, MSE, SPP, flow, total gas + C1C5, gamma, inclination/azimuth, stick-slip/vibration, pit gain-loss, on-bottom, …) with sensible physical default scales so sensor-glitch spikes clip instead of flattening the trace.
  • Log Plot: index vertical (depth or time, with a toggle), value horizontal in side-by-side tracks; min/max envelope + mid trace; scrollbar + wheel-zoom + Fit to navigate; auto-fit (scale each track to the visible window); hover crosshair + readout; curve picker to customize tracks; EDR-style replay (curves scroll like a rig strip-chart); Σ Stats panel (min/avg/max per channel over the window).
  • Crossplot: bucket-mean X vs Y (default WOB vs ROP) colored by depth/time/channel, on-bottom only filter, robust (1st99th pct) auto-ranges so outliers don't blow up the axes, colorbar, hover.
  • Robust axes/depth: hole-depth is jump-capped so one garbage DEPT sample can't poison the depth axis; an axis is only offered when its real extent is non-degenerate.

Layout

las-stream-viewer/
├─ pom.xml                      Quarkus 3.34.3, Java 21
├─ run.ps1                      dev: Vite (:5173) + Quarkus (:8090)
├─ build.ps1                    prod: bundle UI into the jar, serve on :8090
├─ src/main/java/com/oiusa/las/
│  ├─ model/                    LasFile, Curve, HeaderSection, ResolvedRole
│  ├─ index/                    LineIndex (sparse offsets), LineReader, Pyramid (min/max/mean overview), RowParser
│  ├─ service/                  FileStore, IndexService (one-pass index+pyramid), LasHeaderParser,
│  │                            ChannelRoles (role mapping), CurveDataService (decimation/crossplot), UploadService
│  └─ web/                      File / Lines / Stream(SSE) / Search(SSE) / Upload / Curve (roles, curve-data, crossplot)
└─ frontend/src/
   ├─ components/               App, IngestPanel, FileList, Section, WellInfo, ChannelList,
   │                            HeaderPanel, Viewer (raw), LogPlot, Crossplot
   └─ api.ts, types.ts, las.ts, styles.css

Run (dev)

cd C:\Users\Dell\Desktop\las-stream-viewer
.\run.ps1

Installs UI deps on first run, starts Vite in a new window, runs the Quarkus dev server. Open http://localhost:5173.

By hand:

$env:JAVA_HOME="C:\Program Files\Java\jdk-21.0.11"
$mvn = "C:\Users\Dell\.m2\wrapper\dists\apache-maven-3.9.9-bin\4nf9hui3q3djbarqar9g711ggc\apache-maven-3.9.9\bin\mvn.cmd"
& $mvn quarkus:dev                 # backend :8090
cd frontend; npm install; npm run dev   # frontend :5173 (separate window)

Run (production, single port)

.\build.ps1
$env:JAVA_HOME="C:\Program Files\Java\jdk-21.0.11"
java -jar target\quarkus-app\quarkus-run.jar
# open http://localhost:8090

Using it

  1. Open a file (left panel): Open on disk browses the server filesystem (constrained to las.allowed-roots) and opens a .las in place, no copy — ideal for the multi-GB logs. Or Upload to stream a file in 16 MiB chunks. Indexing + the curve overview build in the background; the well info and channels appear in the sidebar as soon as the header is parsed.
  2. 📈 Log Plot — scroll the scrollbar (or wheel-zoom / Fit) through depth or time, hover for a readout, ▶ Replay to animate, toggle auto-fit and Σ Stats, add channels via Curves.
  3. ⊕ Crossplot — pick X/Y/Color, toggle on-bottom only for a clean founder-point view.
  4. 𝍌 Raw / QC — stream the raw lines (speed slider), jump to Top/Data/End/any line, search the whole file. Good for verifying export integrity (column alignment, NULLs, etc.).

Collapse the left panel with the button in the top bar for a bigger workspace.

Notes & caveats

  • The channel→role mapping is auto-resolved from mnemonics; verify with the Curves picker and swap channels if a mapping looks off for your file.
  • Data quality is the data's own: some exports have broken channels (e.g. a stuck DEPT), in which case that axis is suppressed and the Raw / QC tab is the place to confirm. Sensor-glitch spikes are handled by fixed physical scales (Log Plot) and robust percentile ranges (Crossplot).
  • First index of a 12.5 GB file takes a few minutes (it parses ~40 channels/row for the pyramid); shown with a progress bar. Smaller logs index in seconds.

Configuration (src/main/resources/application.properties)

Key Default Notes
quarkus.http.port 8090 API (and prod UI) port
las.data-dir ${user.home}/.las-stream-viewer where uploaded files live
las.allowed-roots ${user.home} local files may only be opened from under these roots
las.index-stride 256 lines per index checkpoint (smaller = faster seeks, larger index)
las.upload-chunk-size 16777216 upload chunk size hint (16 MiB)