Last updated

Memory Reader

This tutorial demonstrates how seismic data can be stored in memory and displayed in a SeismicViewWidget. This example uses MemoryReader which allows working in synchronous and asynchronous modes. In the synchronous mode, the reader calls the several callbacks to provide trace samples "getTraceData", trace headers "getTraceHeader" and data statistics to get results immediately. This mode is appropriate to use if data is stored completely in the memory. In the asynchronous mode the reader calls "getAsyncData" and passes a callback function that must be called when data is received. This approach can be used for data located on the server and memory reader can be considered as a query manager. The code below creates a memory reader and fills traces by request using asynchronous mode.

# Creating a Seismic MemoryReader

The code below creates a new empty reader. The image above shows several samples from two first traces.

# Display this Seismic in a Widget

The code below creates a pipeline, passes an instance of the reader, and creates a SeismicViewWidget to display the data.

import { SeismicViewWidget } from "@int/geotoolkit/seismic/widgets/SeismicViewWidget.ts";
import { SeismicPipeline } from "@int/geotoolkit/seismic/pipeline/SeismicPipeline.ts";
import { SeismicColors } from "@int/geotoolkit/seismic/util/SeismicColors.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { Text } from "@int/geotoolkit/scene/shapes/Text.ts";
import { MemoryReader } from "@int/geotoolkit/seismic/data/MemoryReader.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
function createScene(memoryReaderCanvas, widgetCanvas) {
  const sampleRate = 1;
  const sampleCount = 250;
  const traceCount = 350;
  const reader = new MemoryReader({
    "numberoftraces": traceCount,
    "numberofsamples": sampleCount,
    "samplerate": sampleRate
  }).setTraceProcessor({
    "getAsyncData": (query, callback) => {
      callback({ "getTraceData": (reader2, samples, traceId) => {
        for (let i = 0; i < reader2.getNumberOfSamples(); i++) {
          samples[i] = Math.cos(i / 8);
        }
      } });
    },
    "getDataStatistics": () => ({
      "average": 0,
      "min": -1,
      "max": 1,
      "rms": Math.sqrt(2) / 2
    })
  });
  let shapesGroup;
  reader.select({
    "from": 0,
    "to": 10
  }, (result) => {
    const shapes = [];
    let i;
    const COLUMN_WIDTH = 140;
    for (i = 0; i < 2; i++) {
      shapes.push(
        new Text({
          "text": "Trace # " + i,
          "ax": i * COLUMN_WIDTH + COLUMN_WIDTH / 2,
          "ay": 0,
          "alignment": AnchorType.TopCenter
        })
      );
    }
    const tmpBuffer = [];
    for (i = 0; i < 2; i++) {
      const trace = result.getTrace(i);
      trace.getSamples(tmpBuffer);
      for (let j = 0; j < 13; j++) {
        shapes.push(
          new Text({
            "text": tmpBuffer[j].toFixed(12),
            "ax": i * COLUMN_WIDTH + COLUMN_WIDTH / 2,
            "ay": j * 15 + 30
          })
        );
      }
    }
    for (i = 0; i < 2; i++) {
      shapes.push(
        new Text(
          {
            "text": "...",
            "ax": i * COLUMN_WIDTH + COLUMN_WIDTH / 2,
            "ay": 13 * 15 + 30
          }
        )
      );
    }
    shapes.push(
      new Text({
        "text": "...",
        "ax": i * COLUMN_WIDTH,
        "ay": 13 / 2 * 15 + 30,
        "alignment": AnchorType.LeftCenter
      })
    );
    shapesGroup = new Group().setAutoModelLimitsMode(true).addChild(shapes);
  });
  const plots = [];
  plots.push(new Plot({
    "canvaselement": memoryReaderCanvas,
    "root": shapesGroup
  }));
  let stats = null;
  reader.readDataSetStatistics((reader2, statistics) => {
    stats = statistics;
  });
  const pipeline = createPipeline(reader, stats);
  const widget = createWidget(pipeline);
  plots.push(new Plot({
    "canvaselement": widgetCanvas,
    "root": widget
  }));
  return plots;
}
function createPipeline(reader, stats) {
  const colorProvider = SeismicColors.getDefault();
  return new SeismicPipeline({
    "name": "MemorySeismic",
    "reader": reader,
    "statistics": stats
  }).setOptions({
    "colors": {
      "colormap": colorProvider.createNamedColorMap("WhiteBlack", 32)
    },
    "plot": {
      "type": {
        "wiggle": false,
        "interpolateddensity": true
      }
    }
  });
}
function createWidget(pipeline) {
  return new SeismicViewWidget({
    "pipeline": pipeline,
    "colorbar": {
      "axis": {
        "tickgenerator": {
          "edge": {
            "tickvisible": false,
            "labelvisible": false
          }
        }
      }
    },
    "layouttype": "inside",
    "scroll": {
      "horizontal": {
        "visible": true,
        "cssclass": "horizontal-scroll",
        "type": "geotoolkit.controls.tools.scroll.HorizontalScroll",
        "options": {
          "rounded": true
        }
      },
      "vertical": {
        "visible": true,
        "cssclass": "vertical-scroll",
        "type": "geotoolkit.controls.tools.scroll.VerticalScroll",
        "options": {
          "rounded": true
        }
      }
    }
  }).setScaleOptions({
    "tracescale": 10,
    "samplescale": 50,
    "deviceunit": "in",
    "sampleunit": "ms"
  });
}
export { createScene };

createScene(document.querySelector('[ref="MemoryReader"]'), document.querySelector('[ref="Widget"]'));