Skip to content
Last updated

Sending Large Volumes To Matlab

For very large files the data must be buffered so that large arrays do not have to be allocated.

        ISeismicData seismicData = (ISeismicData)IData.factory.createNewInstance("myData.xgy");
        ISeismicReader reader = seismicData.select(new SeismicRangeQuery());
        IMatlabProxy proxy = IMatlabConnector.Factory.getInstance().getProxy();
        IKeyRange inlineKey = seismicData.getDataRange().get(0);
        IKeyRange xlineKey = seismicData.getDataRange().get(1);
        ISeismicReader reader = seismicData.select(new SeismicRangeQuery()); //select all data
        IFieldDesc inlineFieldDesc = reader.getTraceHeaderField(inlineKey.getName());
        IFieldDesc xlineFieldDesc = reader.getTraceHeaderField(xlineKey.getName());
        int numInlines = (int) (inlineKey.getMaximum() - inlineKey.getMinimum()) + 1;
        int numXlines = (int) (xlineKey.getMaximum() - xlineKey.getMinimum()) + 1;
        int numberOfSamples = reader.getDataStatistics().getSamplesPerTrace();
        int numberOfTraces = reader.getNumberOfTraces();
        proxy.eval("volume = zeros(" + numInlines + "," + numXlines + "," + numberOfSamples + ");"); //allocate variable in matlab
        Map<Integer, Map<Integer, List<Double>>> volumeData = new HashMap<Integer, Map<Integer, List<Double>>>();
        for (int i = 0; i < numberOfTraces; i++) {
            ITrace trace = reader.getTrace(i);
            float[] samples = new float[numberOfSamples];
            trace.getSamples(samples);
            int inline = trace.getHeader(inlineFieldDesc.getIdentifier()).intValue();
            int xline = trace.getHeader(xlineFieldDesc.getIdentifier()).intValue();
            if (!volumeData.containsKey(inline)) {
                volumeData.put(inline, new HashMap<Integer, List<Double>>());
            }
            Map<Integer, List<Double>> xlines = volumeData.get(inline);
            if (!xlines.containsKey(xline)) {
                xlines.put(xline, new ArrayList<Double>());
            }
            List<Double> sampleData = xlines.get(xline);
            for (int j = 0; j < samples.length; j++) {
                sampleData.add(new Double(samples[j]));
            }
            if (((i + 1) % 10000) == 0 || ((i + 1) == numberOfTraces && !volumeData.isEmpty())) { //write out traces we have so far
                for (Map.Entry<Integer, Map<Integer, List<Double>>> inlineEntries : volumeData.entrySet()) {
                    for (Map.Entry<Integer, List<Double>> xlineEntries : inlineEntries.getValue().entrySet()) {
                        List<Double> values = xlineEntries.getValue();
                        Integer currInline = inlineEntries.getKey();
                        Integer currXline = xlineEntries.getKey();
                        int inlineIndex = (currInline - (int) inlineKey.getMinimum()) + 1; //+1 because indexes start at 1 in matlab
                        int xlineIndex = (currXline - (int) xlineKey.getMinimum()) + 1;
                        for (int j = 0; j < values.size(); j++) {
                            proxy.eval("volume(" + inlineIndex + "," + xlineIndex + "," + (j + 1) + ") = " + values.get(j)+";");
                        }
                    }
                }
                volumeData.clear();
            }
        }

Note: This method can be further optimized by sending larger arrays that can then be copied into the volume variable.