Note: You will need to include HorizonData to your Module Dependencies list.
We load an horizon called filename and print the access keys' name and range. If your application requires a file chooser for selecting the horizon file, you can use the one provided with INTViewer. See section Using the Horizon File Chooser below for an example.
import com.interactive.intviewerapi.data.IData;
import com.interactive.intviewerapi.data.horizon.IHorizonData;
import com.interactive.intviewerapi.data.horizon.IHorizonDataCollection;
...
try {
IHorizonDataCollection hd = IData.factory.createNewInstance(filePath, IHorizonDataCollection.class);
} catch (Exception ex) {
DialogManager.getDefault().showMessageDialog("Error loading horizon: " + filePath,
"Error Loading Horizon", DialogManager.ERROR);
return;
}
for (IHorizonData shd: hd.getAllHorizonData()){
List<IKeyRange> klist = shd.getDataRange();
for (IKeyRange kr:klist) {
System.out.println(kr);
}
}
Internally, the default factory uses Netbeans FileObject and DataObject to load the horizon. Netbeans filesystem supports the notion of a data pool, so that if you open several times the same file, you will get the same data object instance.
This example shows how to let a user select a horizon file using the built-in horizon file selection dialog in INTViewer. The chooser is automatically setup to filter valid horizon filenames.
To select one dataset:
import com.interactive.intviewerapi.data.ISingleDataChooser;
// get the chooser for horizon data type
ISingleDataChooser<IHorizonDataCollection> singleChooser = ISingleDataChooser.Factory.createNewInstance(IDataChooser.HORIZON);
// popup the chooser dialog
int rc = singleChooser.setDataChooserVisible(true);
if (rc == JFileChooser.APPROVE_OPTION) {
IHorizonDataCollection horizonData = singleChooser.getSelectedData();
}
To select multiple datasets:
import com.interactive.intviewerapi.data.IMultipleDataChooser;
// get the file chooser for horizon data type
IMultipleDataChooser<IHorizonDataCollection> multipleChooser = IMultipleDataChooser.Factory.createNewInstance(IDataChooser.HORIZON);
// popup the chooser dialog
int rc = multipleChooser.setDataChooserVisible(true);
if (rc == JFileChooser.APPROVE_OPTION) {
for (IHorizonDataCollection sdata : multipleChooser.getSelectedData()) {
}
}
Range keys provide information about how to access the horizon data. They can be accessed as follows:
List<IKeyRange> keyRangeList = hd.getDataRange();
Unlike in seismic datasets, the last key of a horizon dataset is usually NOT the time key as it is a non-indexed attribute. The key names of a horizon are typically INLINE and XLINE. Time, Amplitude are usually non-indexed attributes.
We create a horizon with two access keys (INLINE and XLINE) and two non-indexed attribute fields (Time and Amplitude).
import com.interactive.intviewerapi.data.horizon.HorizonUtil;
import com.interactive.intviewerapi.data.FieldDesc;
...
IHorizonData hd = HorizonUtil.createHorizonData("tmp",
new FieldDesc[]{
new FieldDesc("INLINE", 0, true),
new FieldDesc("XLINE", 1, true),
new FieldDesc("Time", 2),
new FieldDesc("Amplitude", 3)
});
There is no limit in terms of the number of access keys or attributes that you can specify.
The following example shows how to populate the empty horizon created in the previous section.
import com.interactive.intviewerapi.data.PointData;
...
for (int inline= 0; inline < 400; inline++) {
for (int xline = 0; xline < 400; xline++) {
PointData pd = hd.createPointData();
pd.setValues(new float[] {inline, xline,
inline*0.1f, (xline+inline)*13.45f});
hd.addPointData(pd);
}
}
Each time a point is added, a PointDataEvent is sent. This can cause performance issues when a large number of points has to be added. Wrap this code inside a IHorizonData.update method to reduce the event overhead.
hd.update(new Runnable() {
@Override
public void run() {
for (int inline= 0; inline < 400; inline++) {
for (int xline = 0; xline < 400; xline++) {
PointData pd = hd.createPointData();
pd.setValues(new float[] {inline, xline,
inline*0.1f, (xline+inline)*13.45f});
hd.addPointData(pd);
}
}
}
});
We delete all the points within INLINE 20-21 and XLINE 30-31.
import com.interactive.intviewerapi.data.IPointSelection;
import com.interactive.intviewerapi.data.KeyRange;
import com.interactive.intviewerapi.data.query.RangeQuery;
...
RangeQuery rq = new RangeQuery();
rq.addKeyRange(new KeyRange("INLINE", 20, 21 ));
rq.addKeyRange(new KeyRange("XLINE", 30, 31 ));
IPointSelection ps = hd.select(rq);
hd.delete(ps);
We retrieve all the points for INLINE 40.
RangeQuery rq = new RangeQuery();
rq.addKeyRange(new KeyRange("INLINE", 40, 40 ));
IPointSelection ps = hd.select(rq);
List<PointData> dataList = ps.getData();
You could do the following to save a horizon:
ISingleDataSaver ds = ISingleDataSaver.Factory.createNewInstance(IDataChooser.HORIZON);
if (ds.setDataSaverVisible(true, horzData.getDataPath(), horzData) == JFileChooser.APPROVE_OPTION) {
HorizonDataCollection savingHorizons = HorizonUtil.createHorizonDataCollection("temp");
savingHorizons.addHorizonData(horzData);
FileObject fo = (FileObject) ds.saveDataAndWait(savingHorizons);
if (fo != null) {
String absoluteDataPath = FileUtil.toFile(fo).getAbsolutePath();
if (horzData.getDataPath() == null || horzData.getDataPath().length() == 0) {
horzData.setDataPath(absoluteDataPath);
}
}
}
This would display a dialog to let the users select the fileName in which they want to save the IHorizonData.
Note: in your project module properties, you will need to include File System API to your Module Dependencies list.
This example shows how to extract a single IHorizonData object out of an IData object that could be IHorizonData or IHorizonDataCollection.
if (data instanceof IHorizonData) {
return (IHorizonData) data;
} else if (data instanceof IHorizonDataCollection) {
IHorizonData currentData = null;
if (data.getDataName() != null) {
currentData = ((IHorizonDataCollection) data).getHorizonData(data.getDataName());
}
if (currentData == null) {
currentData = ((IHorizonDataCollection) data).getAllHorizonData()[0];
}
return (IHorizonData) currentData;
} else {
return null;
}