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.