[OpendTect_Developers] How to work with OpendTect horizons (part 1, reading)

Nanne Hemstra nanne at opendtect.org
Tue Sep 28 11:24:36 CEST 2010


Hi all,

When you're writing a plugin, there's a high chance that one day you 
want to work with OpendTect horizons. This post gives some background 
information and example code for reading horizons.

As you probably know all data objects in OpendTect have a unique id, 
what we call a MultiID. For horizons this id looks like '100020.#',
where # is a number starting from 2. The id for a particular object can
be found in the .omf file of the corresponding data directory of the 
survey. For horizons this is the 'Surfaces' directory.

Horizons are part of OpendTect's EarthModel (EM). Therefore we need the
EMManager, the manager of all EM objects, to read the horizon from disk.
The EMManager class has a couple of functions to read EMObjects. One of
them is 'objectLoader'. This function takes the MultiID and a
SurfaceIODataSelection as arguments and returns an Executor. Executing
the executor will load the horizon into our EarthModel.
When the executor is finished, the horizon is in memory, and we'd like
to have a pointer to the EM::Horizon object. If I turn this into source 
code it looks like this:

<code>
PtrMan<Executor> loader = EM::EMM().objectLoader( multiid );
if ( !loader || !loader->execute() )
      return;

EM::ObjectID emid = EM::EMM().getObjectID( multiid );
EM::EMObject* emobj = EM::EMM().getObject( emid );
mDynamicCastGet(EM::Horizon*,horizon,emobj);
</code>

The horizon can be a 2D or 3D horizon. In case you want a 3D horizon,
use: mDynamicCastGet(EM::Horizon3D*,horizon3d,emobj);


Before we look into acquiring Z values, some more background information:

The horizon grid is defined as rows and columns. Rows are the inlines,
columns the crosslines. Each row/col (or inl/crl) can have 1 Z-value. If 
you need a second Z-value, you'll have to add a new section. So here we 
immediately have the definition of a section: A grid with one value per 
grid node. Note that all OpendTect horizons have just one section.
Support for multiple sections will be added later.

When retrieving positions from an EMObject, you'll encounter 3 EM 
specific objects:
- EM::SectionID : The id of a section
- EM::SubID : a 64 bit integer where the first 32 bits contain the row
number and the last 32 bits the column number.
- EM::PosID : position information, includes emobjid, sectionid and subid.


OK, now the real work ...
If you'd like to know the Z value for a particular inline and crossline
(BinID), use:

<code>
EM::SectionID sid = horizon3d->sectionID( 0 );
BinID bid( inl, crl );
EM::SubID subid = bid.toInt64();
float z = horizon3d->getPos( sid, subid );
</code>


Much easier though, is to use the EMObjectIterator:

<code>
EM::EMObjectIterator* iter = horizon3d->createIterator( -1 );
while ( true )
{
      const EM::PosID posid = iter->next();
      if ( posid.isUdf() ) break;

      const Coord3 crd = horizon3d->getPos( posid );
      const float z = crd.z;
      const BinID bid( posid.subID() );
}
</code>


Finally you can get all Z-values in an Array2D:

<code>
EM::SectionID sid = horizon3d->sectionID( 0 );
Array2D<float>* arr = horizon3d->createArray2D( sid );
</code>


Please find attached some example code. The code reflects a uiDialog,
with one input field (a uiSurfaceRead) and the horizon reading process
as described above.


Best regards,

Nanne



-- 
Nanne Hemstra
OpendTect developer

dGB Earth Sciences
304, Gateway Plaza
Hiranandani Gardens, Powai
Mumbai - 400 076, India
Phone: +91 22 25704984 , Fax: +91 22 25704977
http://www.opendtect.org

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: uiloadhorizons.cc
URL: <http://lists.opendtect.org/pipermail/developers/attachments/20100928/71bb26cd/attachment.cc>


More information about the Developers mailing list