122 lines
6.5 KiB
Markdown
122 lines
6.5 KiB
Markdown
# 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 + C1–C5, 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 (1st–99th 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)
|
||
|
||
```powershell
|
||
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:
|
||
|
||
```powershell
|
||
$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)
|
||
|
||
```powershell
|
||
.\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) |
|