MasterSuite

usage in

HEPInventor

October 1998
Olivier Couet
CERN Geneva, Switzerland

Abstract

This aim of the memorandum is to describe how MasterSuite is used in the HEPInventor package. The primary goal of a such description is to have some feedback from MasterSuite experts (ie TGS) to make sure that, regarding the requirements we have, the implementation of the HEPInventor package is the best we can do. We also explain the problems we have encountered.

Finally we have benchmarked the Iris Explorer modules made with HEPInventor . The results we obtained are very bad compared to the PAW system. The results of these benchmarks are given at the end of the memorandum.


Overview


What is HEPInventor

HEPinventor has already been described in several papers. HEPInventor is a data drawing (presentation) class library. The basic idea of this class library is to provide an easy to use API making the link between the user data (histOOgram or vectors) and graphics. HEPInventor is based on the MasterSuite class library (provided by TGS) , itself based on OpenInventor.

HEPInventor has been used to build IRIS Explorer modules doing screen and PostScript output of user data in an interactive environment (IRIS Explorer).

Basic concepts

The HEPInventor class library is built around 3 basic classes:
  1. The Page (class HIPage): is a 2D space defined in centimeters in which the HEPInventor user compose the image he wanted to produce. A page is composed with zones. Once created a page can be converted (draw) into an OpenInventor scene graph which can be displayed on the screen via a viewer or output on a file (Postscript, IV, HPGL). The page drawing consist of the page drawing itself and the drawing of all the zones inside the page.
  2. The Zone(s) (class HIZone): is the basic unit used to compose a page. It cannot be displayed if it is not included in a page. The zone position within a page is defined in the page coordinates (cm). When a zone is included in a page, the page check that the zone position is correct (inside the page coordinates). A zone can be included in several pages. The zone is a ``container'' for the data. A zone may contains several data. A zone has several attributes: it can have linear or log coordinates, it can have a grid or not, the background color can be modified. The zone drawing consist of the zone drawing itself and the drawing of all the datas inside the zone.
  3. The Data(s) (class HIData): is the ``graphics transposition'' of a data set (mainly vectors or histograms). A ``data'' has to be put into a zone to be drawn. A ``data'' has several attributes like the way it is represented (errors, stairs etc ..), the color, the line width etc ... .

Classes library overview

Three basic classes are provided:
  1. HIPage : Contains HIZone(s). Can be displayed on the screen (via the window class), printed via PostScript files or output as an Inventor file. The page size is defined in centimeters.
  2. HIZone : Contains HIData(s). Can be placed anywhere on a Page. This class is used to define the layout of the page. The zone position in the page is given in centimeters.
  3. HIData : Does the interface between user data and graphics. User data can come from various sources. The class HIData allows to disconnect the data from the graphics representation. If a new type of data has to be drawn by the HEPInventor package it is enough to create a new constructor which accepts this new data type keeping unchanged the other parts of the package.
The following example shows how to use the ``HI'' classes:
#include "HInventor.h"
      int main()
      {
      #define PI 3.1415
      #define N  50

       HIPage P;                           // creates a HIPage P (20x20 cm)
       HIZone Z(2.,18.,2.,18.);            // creates a HIZone Z
       P.AddZone(&Z);                      // puts the HIZone Z in the HIPage P

       Z.set(HIZone::YGradLabelSize,0.7);  // changes Y label size
       Z.set(HIZone::XGradLabelSize,0.7);  // changes X label size

       float X[N],SINX[N],COSX[N];         //
       float ANGLE = 0;                    //
       float DX    = 2*PI/N;               //
       int i;                              // generates 2 floating points 
       for ( i=0; i < N; i++) {            // arrays one containing a sin and
          X[i]    = ANGLE;                 // this other one a cos.
          SINX[i] = sin(ANGLE);            //
          COSX[i] = cos(ANGLE);            //
          ANGLE   = ANGLE+DX;              //
       }                                   //

       HIData SINDATA(N,X,SINX);           // creates a Data set SINDATA
       HIData COSDATA(N,X,COSX);           // creates a Data set COSDATA
       
       Z.AddData(&SINDATA);                // puts SINDATA in the HIZone Z
       Z.AddData(&COSDATA);                // puts COSDATA in the HIZone Z

       HIPostScript(&P, "Ex002.ps");       // generates the PS file Ex002.ps from P
       return 0;
      }
This example produce the following output:

To have a complete and detailed description the HEPInventor class library see the HEPInventor manual.


Requirements

General graphics requirements for data presentation in High Energy Physics (HEP) are explained in the document called ``HEP graphics requirements for data presentation''. In this section we present more ``technical'' issues involving MasterSuite usage. These points are all related to the page geometry and the various coordinate spaces management.
  1. The zones should be positionned in a cm space (the page). To allow a ``natural'' positionning of the zones within the page, it has been decided that the zone position will be defined at the zone creation time in centimeters. The coordinates of the lower left and upper right corners of the zone are defined in the page coordinates.
  2. The axis label size, axis title etc ... should defined in the page coordinates (cm) independently of the zone coordinates. It is very difficult to manage the texts sizes if there are not defined in unique coordinate space. Having them defined in the data coordinate system is not good because the text size depend on the range of the date presented. That why it has been decided to define text sizes in the page coordinate (cm).
  3. The aspect ratio of the zone position in the page and the aspect ratio of the zone coordinate space may be different (in fact most of the time they are different). This seems obvious but this is not an easy requirements to achieve with MasterSuite/OpenInventor.

Solutions adopted

In order to implement the requirements defined in the previous section, the HIZone class define 3 PbDomain and 3 Views:
  1. The data domain and view are respectively used to define the space coordinate in which data are drawn and place the data drawing correctly (according to the zone position is the page).
  2. The axis require a special domain and view definition mainly because MasterSuite doesn't make the difference between the axis position and the axis labeling. At the axis creation time, only one set of parameter define both. To bypass this limitation we define an axis domain whose aspect ratio matches the page dimension with space coordinates containning the zone coordinates. Then, having this domain defined with the page aspect ratio allows an easy setting of the geometrical axis attributes (label size, tickmarks sizes etc ..), which are defined in % of the domain, indepently from the zone coordinates.
  3. The centimeters domain and view matches exactly the page size and has its space coordinates defined in centimeters. This domain is used to draw objects like PoLabelField (use to draw the histogram statistics) which have their geometrical attributes define in domain coordinates (not in % of the domain like the axis).
Two procedures are used to define the Domains and the Views. To define the domains we use HIDefineDomain:
//-----------------------------------------------------------------------------
//
// Define a domain according to its position in cm and its axis coordinates
//
PbDomain* HIDefineDomain(float X1P, float X2P, float Y1P, float Y2P,
                         float X1A, float X2A, float Y1A, float Y2A)
{
   PbDomain *domain = new PbDomain;
   float dxv = X2P-X1P;
   float dyv = Y2P-Y1P;
   float R   = dxv/dyv;
   float xd2 = X2A;
   float yd2 = Y2A;
   if (dxv > dyv) {
      yd2 = (Y2A-Y1A)*R + Y1A;
    } else {
      xd2 = (X2A-X1A)/R + X1A;
    }
   domain->setDomain(X1A, Y1A, xd2, yd2);
   return domain;
}
To define the views we use HIDefineView. This procedure allows to positionned a zone in a page. It takes the zone position in centimeters and define the corresponding PoSceneview in normalized coordinates. The conversion between centimeters and normalized coordinates is done via conversion methods provided by the HIPage class.
//-----------------------------------------------------------------------------
//
// Define a view in cm coordinates.
//
PoSceneView* HIDefineView(float X1, float X2, float Y1, float Y2,
                          HIPage *page, SoSeparator *SceneGraph)
{
   PoSceneView *view;
   view = new PoSceneView() ;
   view->sensitiveOnEvents(TRUE) ;
   view->viewportOrigin.setValue(page->XCm2View(X1), page->YCm2View(Y1)) ;
   view->viewportSize.setValue(page->XCm2View(X2)-page->XCm2View(X1),
                               page->YCm2View(Y2)-page->YCm2View(Y1)) ;
   SoOrthographicCamera *camera = new SoOrthographicCamera ;
   view->setPart("cameraKit.camera", camera) ;
   view->setPart("scene", SceneGraph) ;
   camera->viewAll(SceneGraph, SbViewportRegion(100, 100)) ;
   return view;
}
Domain definition in HIZone:
//
// Data Domain
//
   SoSeparator *DataSceneGraph = new SoSeparator;

   PbDomain *DataDomain = new PbDomain;
   DataDomain->setTransformType(PbDomain::TRANSFORM_01);

   DataDomain = HIDefineDomain(X1ZonePos, X2ZonePos, Y1ZonePos, Y2ZonePos,
                               X1ZoneAxis, X2ZoneAxis, Y1ZoneAxis, Y2ZoneAxis);
//
// Axis domain.
//
   SoSeparator *AxisSceneGraph = new SoSeparator;

   PbDomain *AxisDomain = new PbDomain;
   AxisDomain->setTransformType(PbDomain::TRANSFORM_01);

   float x1 = XCm2Zone(0.);
   float x2 = XCm2Zone(page->PageWidth);
   float y1 = YCm2Zone(0.);
   float y2 = YCm2Zone(page->PageHeight);

   AxisDomain = HIDefineDomain(0., page->PageWidth, 0., page->PageHeight,
                               x1, x2, y1, y2);

//
// Centimeters domain.
//
   SoSeparator *CMSceneGraph = new SoSeparator;

   PbDomain *CMDomain = new PbDomain;
   CMDomain->setTransformType(PbDomain::TRANSFORM_01);

   CMDomain = HIDefineDomain(0., page->PageWidth, 0., page->PageHeight,
                             0., page->PageWidth, 0., page->PageHeight);
View definition in HIZone:
   PoSceneView *DataView;
   DataView = HIDefineView(X1ZonePos, X2ZonePos, Y1ZonePos, Y2ZonePos,
                           page, DataSceneGraph);
   PageSceneGraph->addChild(DataView) ;

   PoSceneView *AxisView;
   AxisView = HIDefineView(0., page->PageWidth, 0., page->PageHeight,
                           page, AxisSceneGraph);
   PageSceneGraph->addChild(AxisView) ;

   PoSceneView *CMView;
   CMView = HIDefineView(0., page->PageWidth, 0., page->PageHeight,
                           page, CMSceneGraph);
   PageSceneGraph->addChild(CMView) ;

Problems encountered

  1. The clipping doesn't work like expected: the system always try to put everything visible in the domain.To illustrate the problem we have changed the axis label sizes to 2.0cm in the previous example. With most graphical systems the text would have been clipped on the viewport boundary. MasterSuite (OpenInventor) doesn't. Instead it tries to display the text completly (except the "-".. why ?) which shifted the axis and produce the completly wrong picture below:
  2. According to TGS this problem should be fixed in OIV 2.5 / 3DMS 3.5
  3. The bounding box of a PbDomain should be always drawn otherwise the content of the PbDomain is stretched to the PbDomain boundary in order to fulfill it.
  4. To illustrate this problem we have modified the HIZone creation in the example in order to have HIZone limits bigger than the data limits:

     HIZone Z(2.,18.,2.,18.,0.,8.,-2.,2.);       // create a HIZone Z
    HEPInventor draws the bounding box of the DataDomain in order to have the right picture so the picture produced is the following:

    Then we have commented out the drawing of the bounding box DataDomain in the HEPInventor code and the picture obtained is the following which is obviously completly wrong:

  5. When HEPInventor pictures (scene graph(s)) are displayed with a viewer (for example in the Render window of IRIS Explorer), they cannot be rotated. This is due to the following code inside the HIDefineView routine:
  6.    SoOrthographicCamera *camera = new SoOrthographicCamera ;
       view->setPart("cameraKit.camera", camera) ;
    If this code is removed the picture can be rotated but the graphics output obtained is wrong:
  7. To draw boxes, the class PoRectangle should be use. It works fine when it is displayed on screen. When it is output on a PostScript file it is also good if the box is Filled. But if only the outline of the box is drawn (hollow mode), the diagonal of the box is drawn because the Mastersuite PostScript driver convert all the primitives into triangles. This prevent us to use PoRectangle to draw boxes outline. We use PoCurve instead.
  8. The quality of text PostScript output is very poor because PostScript fonts are not used. This is done like that in order to be able to rotate the text. In most of our cases, the text in not rotated and is drawn in the screen plane (annotation text) for this type of text PostScript fonts could be used. Also using PostScript font will reduce the size of the PostScript files generated. It could be useful to use ``annotation text'' ito draw axis labels, titles etc ...According to TGS this problem should be fixed in OIV 2.5 / 3DMS 3.5