WellLog Library


WellLog Example

The following example (see file wellog_1.c in directory examples) illustrates how to create two Track widget inside a WellLog widget. Each Track widget contains a log curve a a lithology object. The scrolling of the two tracks is synchronized.

    #include <stdio.h>
    #include <Xm/Xm.h>
    #include <Xm/ScrollBar.h>
    #include <Xint/WellLog.h>
    #include <Xint/Axis.h>
    #include <Xint/Track.h>
    #include <Xint/Osd.h>
    #include <Xint/Lithology.h>

    /* declare subroutines */
    static void BuildUI();

    /* declare global variables */
    Widget toplevel_widget;

    main(argc, argv)
    int argc;
    char *argv[];
    {
       XtAppContext app_context;

       toplevel_widget = XtAppInitialize (&app_context, "Example", NULL, 0,
                                          &argc, argv, NULL, NULL, 0);
       BuildUI ();

       XtRealizeWidget(toplevel_widget);
       XtAppMainLoop(app_context);
    }

    /***
     *** BuildUI
     ***/
    static void
    BuildUI()
    {
        Widget track1, track2;        /* Track widgets */
        Widget well;                  /* WellLog containing the tracks */
        Widget vsb;                   /* vertical ScrollBar */
        Widget haxis1, haxis2;        /* horizontal Axis widgets */
        Object log1, log2;            /* log curves */
        Widget depth_axis;            /* depth Axis */
        float top = 7000;             /* starting value for depth Axis */
        float bottom = 9000;          /* ending value for depth Axis */
        float scale = 150.0;          /* depth scale */
        float porosity_sv = 0;        /* starting value for porosity Axis */
        float porosity_ev = 40;       /* ending value for porosity Axis */
        float density_sv = 1;         /* starting value for density */
        float density_ev = 3;         /* ending value for density */
        float density_major = 1.0;    /* major annotation inc. for density */
        float density_minor = .5;     /* minor annotation inc. for density */
        Object lithology1;            /* lithology object */
        Object lithology2;            /* lithology object */
        float start_depth, end_depth; /* start and end depth for lithology */
        XColor color;
        Colormap map;
      
        /* Create well log */
        well = XtVaCreateManagedWidget ("well", xintWellLogWidgetClass,
                                        toplevel_widget, XmNspacing, 10, NULL);
      
        /* Create first track */
        track1 = XtVaCreateManagedWidget("track1", xintTrackWidgetClass,
                                         well,
                                         XmNtop, &top,
                                         XmNtop, &top,
                                         XmNbottom, &bottom,
                                         XmNdepthScale, &scale,
                                         XtNwidth, 200,
                                         XtNheight, 500,
                                         XmNgridBelow, False,
                                         XmNbackground, 
                                            WhitePixel(XtDisplay(well), 0),
                                         XmNframe, 
                                            XintFRAME_RIGHT | XintFRAME_BOTTOM,
                                         NULL);
  
        XtVaGetValues (track1, XmNdepthAxis, &depth_axis, NULL);
  
        /* position axis on the left of track1 */
        XtVaSetValues(depth_axis,
                      XmNplacement, XintPLACEMENT_LEFT,
                      XmNopposite, False,
                      XmNgridWidget, track1, NULL);
      
        /* create a horizontal Axis for first track */
        haxis1 = XtVaCreateManagedWidget("haxis1", xintAxisWidgetClass,
                                         well,
                                         XmNlabel, "Porosity",
                                         XmNorientation, XintHORIZONTAL,
                                         XmNstart, &porosity_sv,
                                         XmNend, &porosity_ev, NULL);
      
        /* attach horizontal axis to track1 */
        XtVaSetValues(track1, XmNhorizontalAxis, haxis1, NULL);
      
        /* Create second track */
        track2 = XtVaCreateManagedWidget("track2", xintTrackWidgetClass,
                                         well,
                                         XmNcreateAxis, False,
                                         XmNdepthAxis, depth_axis,
                                         XtNwidth, 200,
                                         XtNheight, 500,
                                         XmNgridBelow, False,
                                         XmNbackground, 
                                            WhitePixel(XtDisplay(well), 0),
                                         XmNframe, 
                                            XintFRAME_RIGHT | XintFRAME_LEFT
                                            | XintFRAME_BOTTOM, 
                                         NULL);
      
        /* create a horizontal Axis for second track */
        haxis2 = XtVaCreateManagedWidget("haxis2", xintAxisWidgetClass,
                                         well,
                                         XmNlabel, "Density",
                                         XmNorientation, XintHORIZONTAL,
                                         XmNstart, &density_sv,
                                         XmNend, &density_ev,
                                         XmNmajorIncrement, &density_major,
                                         XmNminorIncrement, &density_minor,
                                         NULL);
      
        /* attach horizontal axis to track2 */
        XtVaSetValues(track2, XmNhorizontalAxis, haxis2, NULL);
      
        /* create a vertical scrollbar and position it right of track2 */
        vsb = XtVaCreateManagedWidget("vsb", xmScrollBarWidgetClass, well,
                                      XmNplacement,   XintPLACEMENT_RIGHT,
                                      XmNgridWidget, track2,
                                      XmNorientation, XintVERTICAL, NULL);
      
        /* connect depth axis with scrollbar widget */
        XtVaSetValues (depth_axis,
                       XmNgridWidget,  track1,
                       XmNscrollBar,   vsb, NULL);
      
        /* create a log curve inside track1 */
        log1 = (Object) XtVaCreateWidget ("log1",
                                          (WidgetClass) xintOsdObjectClass,
                                          track1,
                                          XmNsensitive, False,
                                          XmNaxis, haxis1,
                                          XmNfilename, "dtrpor.txt",
                                          XmNlineThickness, 2, NULL);
      
        /* create a log curve inside track2 */
        log2 = (Object) XtVaCreateWidget ("log2", 
                                          (WidgetClass) xintOsdObjectClass,
                                          track2,
                                          XmNsensitive, False,
                                          XmNaxis, haxis2,
                                          XmNfilename, "dtrden.txt",
                                          XmNlineThickness, 2, NULL);
      
        /* get colormap */
        XtVaGetValues(track1, XmNcolormap, &map, NULL);
      
        /* create a lithology object inside track1 that extends across */
        start_depth = 7220.0;
        end_depth   = 7280.0;
        XAllocNamedColor(XtDisplay(track1), map, "LightSkyBlue", &color,
                         &color);
        lithology1 = (Object) XtVaCreateWidget("lithology1",
                                         (WidgetClass) xintLithologyObjectClass,
                                         track1,
                                         XmNsensitive, False,
                                         XmNfillColor, color.pixel,
                                         XmNfillFilename, "calcite",
                                         XmNfillStyle, XintFILL_OPAQUE_STIPPLED,
                                         XmNstartDepth, &start_depth,
                                         XmNendDepth, &end_depth, NULL);
                
        /* move lithology to the back so that it does not cover log curve */
        XintEditObjectBack(track1, lithology1);
      
        /* create a lithology  inside track2 that is truncated by log2 */
        start_depth = 7112.0;
        end_depth   = 7190.0;
        XAllocNamedColor(XtDisplay(track2), map, "salmon", &color, &color);
        lithology2 = (Object) XtVaCreateWidget("lithology2",
                                        (WidgetClass) xintLithologyObjectClass,
                                        track2,
                                        XmNsensitive, False,
                                        XmNfillColor, color.pixel,
                                        XmNfillCurve, log2,
                                        XmNfillFilename, "sandstone",
                                        XmNstartDepth, &start_depth,
                                         XmNfillStyle, XintFILL_OPAQUE_STIPPLED,
                                        XmNendDepth, &end_depth, NULL);
}

The output from examples welllog_1.c is shown below:


Figure 19: Output produced by example welllog_1.c.


Component Layout

A WellLog display is usually composed of one or more Track widgets which display the WellLog curve data. Annotation is provided by Axis widgets which are usually located around the Track widgets. In addition, one or more scrollbars can be created to provide horizontal and/or vertical scrolling for the Track widgets.

The WellLog widget class provides the layout for applications that need to display WellLog data. It automatically positions the various widget components, including track, axis and scrollbar widgets, properly.

Track widgets can be aligned horizontally or vertically depending on the value of WellLog resource XmNorientation. Axis and ScrollBar widgets are positioned around the Track widgets contained in the WellLog, as indicated by constraint resource XmNplacement. By default, the reference Track widget (the track around which newly created axes and scrollbars will be placed) is the last one created. Use constraint resource XmNgrid if you want to specify a different Track widget. Axis widgets can be stacked, so that you can have multiple levels of annotation.

An Axis widget can extend over only a portion of a Track, horizontally or vertically, as specified by WellLog constraint resources XmNpercentStart and XmNpercentEnd. If two Axis widgets occupy only a portion of a Track and do not overlap, they will be aligned rather than stacked.

The following code sample (see example track_1.c) illustrates how to create a split track, where two curves each cover half of the track and a third one covers the entire track.

    ...
      /* WellLog widget to hold tracks */
      well = XtVaCreateManagedWidget ("well", xintWellLogWidgetClass,
                                      toplevel_widget,
                                      XmNspacing, 0, NULL);

      /* track widget */
      track1 = XtVaCreateManagedWidget("track1", 
                                       xintTrackWidgetClass, well,
                                       XmNtop, &top,
                                       XmNbottom, &bottom,
                                       XmNdepthScale, &scale,
                                       XtNbackground, 
                                          WhitePixel(XtDisplay(well), 0),
                                       XtNwidth, 500,
                                       XtNheight, 600,
                                       XmNframe, 
                                          XintFRAME_LEFT | XintFRAME_BOTTOM,
                                       NULL);

      /* Allocate some colors */
      XtVaGetValues(track1, XmNcolormap, &colormap, NULL);
      XAllocNamedColor(XtDisplay(track1), colormap, "red", &red, &red);
      XAllocNamedColor(XtDisplay(track1), colormap, "green", &green, &green);
      XAllocNamedColor(XtDisplay(track1), colormap, "blue",  &blue,  &blue);
    
      /* Extract ID of depth axis created by track widget */
      XtVaGetValues (track1, XmNdepthAxis, &depth_axis, NULL);

      /* create a log curve */
      curve1 = (Object) XtVaCreateWidget("curve1",
                                         (WidgetClass) xintOsdObjectClass, 
                                         track1,
                                         XmNcolor, green.pixel,
                                         XmNcreateAxis, True,
                                         XmNfilename, "dtrsw.txt",
                                         XmNlineThickness, 2,
                                         XmNname, "SW",
                                         NULL);

      /* get the ID of the horizontal axis created by curve1 */
      XtVaGetValues ((Widget) curve1, XmNhorizontalAxis, &axis1, NULL);

      /* change axis to occupy only first half of track */
      /* and change the rangle displayed by the axis    */
      start = 0;
      end = 25;
      mji = 5;
      mni = 1.;
      XtVaSetValues (axis1, XmNpercentEnd, 50,
                            XmNcolor, green.pixel,
                            XmNstart, &start,
                            XmNend, &end,
                            XmNmajorIncrement, &mji,
                            XmNminorIncrement, &mni,
                            NULL);

      /* create second log curve */
      curve2 = (Object) XtVaCreateWidget ("curve2",
                                          (WidgetClass) xintOsdObjectClass, 
                                          track1,
                                          XmNcolor, red.pixel,
                                          XmNcreateAxis, True,
                                          XmNlineStyle, XintLINE_ON_OFF_DASH,
                                          XmNdashList, "8, 16, 8, 16",
                                          XmNfilename, "dtrgam.txt",
                                          XmNlineThickness, 2,
                                          XmNname, "Gamma", NULL);

                                          
      
      /* extract ID of horizontal axis created by curve2 */
      XtVaGetValues ((Widget) curve2, XmNhorizontalAxis, &axis2, NULL);
    
      /* change the axis to occupy only second half of track */
      /* and change the range displayed by the axis          */
      start = 0;
      end = 100;
      mji = 25;
      mni = 5;
      XtVaSetValues (axis2, XmNpercentStart,50,
                            XmNcolor, red.pixel,
                            XmNstart, &start,
                            XmNend, &end,
                            XmNmajorIncrement, &mji,
                            XmNminorIncrement, &mni,
                            NULL);

      /* create third curve */
      curve3 = (Object) XtVaCreateWidget("curve3",
                                         (WidgetClass) xintOsdObjectClass, 
                                         track1,
                                         XmNcolor, blue.pixel,
                                         XmNcreateAxis, True,
                                         XmNfilename, "dtrpor.txt",
                                         XmNlineThickness, 2,
                                         XmNsymbol, True,
                                         XmNsymbolSize, 2,
                                         XmNsymbolType, 
                                                  XintSYMBOL_FILLED_DIAMOND,
                                         XmNname, "Porosity",
                                         NULL);
    
      XtVaGetValues((Widget) curve3, XmNhorizontalAxis, &axis3, NULL);
      XtVaSetValues(axis3, XmNcolor, blue.pixel, NULL);

      /* Set the controlling axes of the track/grid to first 2 axes */
      XtVaSetValues(track1, XmNhorizontalAxis, axis1,
                            XmNauxAxisList, &axis2,
                            XmNauxAxisCount, 1, NULL);
    
      /* create vertical scrollbar */
      vbar = XtVaCreateManagedWidget("vbar", 
                                     xmScrollBarWidgetClass, well,
                                     XmNorientation, XmVERTICAL,
                                     XmNplacement,   XintPLACEMENT_RIGHT,
                                     XmNgridWidget,  track1, NULL);

      /* attach scrollbar to depth axis */
      XtVaGetValues (track1, XmNdepthAxis, &depth_axis, NULL);
      XtVaSetValues (depth_axis, XmNgridWidget,  track1,
                                 XmNplacement,   XintPLACEMENT_RIGHT,
                                 XmNscrollBar,   vbar, NULL);
    }

The output produced by example track_1.c is shown below:


Figure 20: Output produced by example track_1.c.


Tracks

The Track widget class provides support for the display and editing of graphic objects that comprise a well log track. The Track widget class provides resources for tailoring the look and feel of a well log track.

The Track widget class defines resources that control the coordinate system and scale in both the depth (or time) direction and the value direction. A coordinate system is defined by specifying the widget ID of a horizontal and vertical Axis widget using Track resources XmNdepthAxis and XmNhorizontalAxis (or resources XmNdepthAxis and XmNverticalAxis if the track is horizontal). If no depth axis is specified when a Track widget is created, the track will create its own axis in the depth direction based on the value of resources XmNtop and XmNbottom. The depth scale is described in either time units (inches/second or cm/second) or depth units (feet/inch or meters/cm).

The coordinates of an object in the value direction are described by the horizontal Axis widget (vertical if Track is horizontal) attached to the Track or by an internally specified Axis widget. The visible amount of data in the depth direction is defined by the size of the Track widget and a percentage specified using Track resource XmNvaluePercent. A value percentage of 100 means that the entire data range is visible in the value direction. A value percentage of 50 means that only half of the data is visible in the value direction.

Scrolling of a Track widget is performed by either attaching a ScrollBar widget to the Track depth Axis widget or by using keyboard translations.


Track Grid Lines

Track grid lines are controlled by the horizontal and vertical Axis widgets attached to the Track widget. The Axis widget class defines the resources controlling whether or not to display major and/or minor grid lines as well as the appearance of the grid lines. If you need to display multiple set of grid lines, you can use Track resource XmNauxAxisList to specify a list of Axis widgets for drawing additional grid lines.

Multiple Axes

Any number of Axis widgets may decorate the borders of a Track widget, allowing for flexibility in displaying log curves with different scales in a given Track widget. To provide consistency in the scrolling, the Track widget ensures that all depth or value Axis widgets used internally by Graphic objects have the same virtual length and size as the Track default depth and value Axis respectively.

Sharing the Depth Coordinate System

Applications that need to display well log data often require multiple Track widgets to share the same depth coordinate system. By default, a Track widget creates its own depth Axis widget. The ID of such an Axis can be obtained using function XtGetValues. Sharing a common depth coordinate system is simply obtained by passing the ID of the depth Axis widget created by the first Track to subsequent Tracks, using resource XmNdepthAxis. Furthermore, if the depth Axis widget is connected to a ScrollBar widget, all Track widgets will scroll simultaneously in the depth direction.

Using Multiple Axis Widgets

The controlling Axis widgets, specified by resources XmNverticalAxis and XmNhorizontalAxis, are responsible for drawing the Track widget's grid lines. Additional levels of annotation can be obtained by specifying a list of additional Axis widgets using the resource, XmNauxAxisList. This resource is useful for displaying multiple grid lines or splitting a Track widget into multiple sections, each controlled by a different Axis widget.

Resizing

Resize policy resources are provided for both the depth and value directions, to control whether more or less of the data is shown when the window is resized, or whether the Track is rescaled to show the same amount of data as before the resize operation.

Log Curve Objects

LogCurve objects can be created inside a Track widget. The data used for a LogCurve object is specified using a one dimensional array containing the sample values. A second array, the depth array, can also be specified if the sample values are not evenly spaced in depth.

The LogCurve object class supports a wide range of fill options. An application can fill a LogCurve from the beginning or the end of the track or from any specified values. It is also possible to fill the region between two log curves, to clip a Lithology object to a log curve, etc.

The following code sample (see example log_1.c) illustrates how to fill between two log curves.

    ...
      /* allocate color used for  filling between the two log curves */
      XAllocNamedColor(XtDisplay(track1), cmap, "yellow", &color, &color);

      /* create two log curves */
      for (i=0; i<NSAMPLES; i++) 
           data1[i] = 95. + 55. * sin((float) i * 0.034);
      for (i=0; i<NSAMPLES; i++) 
           data2[i] = 95. + 55. * cos((float) i * 0.045);

      log1 = (Object) XtVaCreateWidget("log1",
                                       (WidgetClass) xintLogCurveObjectClass, 
                                       track1,
                                       XmNaxis, haxis,
                                       XmNlineThickness, 2,
                                       XmNsampleArray, data1,
                                       XmNtop, &top,
                                       XmNbottom, &bottom,
                                       XmNsampleCount, NSAMPLES, NULL);

      log2 = (Object) XtVaCreateWidget("log2",
                                       (WidgetClass) xintLogCurveObjectClass,
                                       track1,
                                       XmNaxis, haxis,
                                       XmNlineThickness, 2,
                                       XmNfillColor, color.pixel,
                                       XmNfillCurve, log1,
                                       XmNfillAttachment, XintATTACH_CURVE,
                                       XmNsampleArray, data2,
                                       XmNtop, &top,
                                       XmNbottom, &bottom,
                                       XmNsampleCount, NSAMPLES, NULL);

The output produced by example log_1.c is shown below:


Figure 21: Output produced by example log_1.c.


Lithology Objects

The Lithology object class defines a filled rectangular object that represents a geologic or stratigraphic pattern. The size of the rectangle is defined by specifying the top and bottom depth values via the resources XmNstartDepth and XmNendDepth. The rectangle extends from the parent starting value to the parent ending value in the value direction. It is also possible to have the lithology pattern clipped along a LogCurve object in the value direction via the resource XmNfillCurve. The Lithology fill pattern and colors are set using the resources defined in the superclass Graphic.

Marker Objects

The Marker object class provides the visual representation of a line with a name and depth value displayed. Marker objects are primarily used inside Track widgets. The marker line extends across the entire value direction of the Track widget. Visual attributes such as the color and size of the line or the name of the marker are specified using resources from Marker's superclass, the Graphic object class.