Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous
Next: Scalar Results Up: NOTE 216 - Lattice Expression Language Implementation Previous: How It Works

Data Type Conversions

There are two types of conversion going on in these classes, and one can get rather confused between them if not careful.

The first type of conversion (e.g. LatticeExprNode to LatticeExpr<T>) is handled by the casting operator discussed previously. In addition, inside that casting operation are calls to functions like LatticeExprNode::makeFloat which embed an object of class LELConvert into the tree and then at evaluation time LELConvert::eval actually converts the data (i.e. the values of the pixels in the eval interface buffer array) between types so that the LatticeExpr<T> T type is self-consistent with the type of the LELInterface CountedPtr inside LatticeExprNode (and hence the right-type eval functions get picked up in LatticeExprNode).

Let us look a little harder at the conversion functions like LatticeExprNode::makeDouble (and similar expressions) that does the type conversion for the actual data arrays in the LELInterface::eval interface. Here is the implementation

   CountedPtr<LELInterface<Double> > LatticeExprNode::makeDouble() const
   {
       switch (dataType()) {
       case TpFloat:
           return new LELConvert<Double,Float> (pExprFloat_p);
       case TpDouble:
           return pExprDouble_p;
       default:
           throw (AipsError ("LatticeExpr: conversion to Double not possible"));
       }
       return 0;
   }

So what happens is that if a type conversion is required on the LatticeExprNode to which makeDouble is being applied, then the returned CountedPtr<LELInterface<Double>> is assigned to a LELConvert object (which inherits from LELInterface). Otherwise, it just returns the current CountedPtr<LELInterface<Double>> object already active inside the LatticeExprNode (pExprDouble$\scriptstyle \tt p$). The LELConvert object is now embedded in the tree. Note that the actual conversion will happen at evaluation time, not at tree construction time, when the eval function of LELConvert gets called. LELConvert::eval will actually convert the data in the interface buffer between types (just by copying).

Let us look at the actual tree here. Imagine we have

   Lattice<Float> a;
   Lattice<Double> b;
   LatticeExprNode expr = a+b;

The tree, with all like types, would be

   +
a     b

Now however, because a and b are different types, we embed a conversion into the tree. In this case, the Float is converted to a Double.

     +
conv    b
  a

Now let us assign this result of a+b to an output Lattice

   Lattice<Float> c;
   c.copyData(expr);

The type of a+b is Double, and we need to convert it to Float, the type of c. Thus the tree looks like

    conv
     +
conv    b
  a

In summary, type conversions of the actual data are handled by embedding LELConvert objects in the tree where necessary. The embedding is done by the LatticeExprNode::makeXXX functions.


next up previous
Next: Scalar Results Up: NOTE 216 - Lattice Expression Language Implementation Previous: How It Works
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15