ExprNodeSet.h

Go to the documentation of this file.
00001 //# ExprNodeSet.h: Classes representing a set in table select expression
00002 //# Copyright (C) 1997,2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: ExprNodeSet.h 21262 2012-09-07 12:38:36Z gervandiepen $
00027 
00028 #ifndef TABLES_EXPRNODESET_H
00029 #define TABLES_EXPRNODESET_H
00030 
00031 //# Includes
00032 #include <casacore/casa/aips.h>
00033 #include <casacore/tables/TaQL/ExprNodeRep.h>
00034 #include <casacore/tables/TaQL/ExprNodeArray.h>
00035 #include <casacore/casa/Containers/Block.h>
00036 
00037 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00038 
00039 //# Forward Declarations
00040 class TableExprNode;
00041 class IPosition;
00042 class Slicer;
00043 template<class T> class Vector;
00044 
00045 
00046 // <summary>
00047 // Class to hold the table expression nodes for an element in a set.
00048 // </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //# Classes you should understand before using this one.
00057 //   <li> TableExprNodeSet
00058 //   <li> TableExprNodeRep
00059 // </prerequisite>
00060 
00061 // <synopsis> 
00062 // This class is used to assemble the table expression nodes
00063 // representing an element in a set. A set element can be of 3 types:
00064 // <ol>
00065 // <li> A single discrete value, which can be of any type.
00066 //  It can be used for 3 purposes:
00067 //  <br>- A function argument.
00068 //  <br>- A single index in an array indexing operation.
00069 //  <br>- A single value in a set (used with the IN operator).
00070 //        This is in fact a bounded discrete interval (see below).
00071 // <li> A discrete interval consisting of start, end and increment.
00072 //  Each of those has to be an int scalar. Increment defaults to 1.
00073 //  It can be used for 2 purposes:
00074 //  <br>- A slice in an array indexing operation. In that case start
00075 //   defaults to the beginning of the dimension and end defaults to the end.
00076 //  <br>- A discrete interval in a set. Start has to be given.
00077 //  When end is not given, the result is an unbounded discrete interval.
00078 //  For a discrete interval, the type of start and end can also be
00079 //  a datetime scalar.
00080 // <li> A continuous interval, which can only be used in a set.
00081 //  It consists of a start and/or an end scalar value of type int, double,
00082 //  datetime, or string. The interval can be open or closed on one or
00083 //  both sides.
00084 // </ol>
00085 // Note the difference between a discrete and a continuous interval.
00086 // E.g. the discrete interval 2,6 consists of the five values 2,3,4,5,6.
00087 // The continuous interval 2,6 consists of all values between them.
00088 // <br>Further note that a bounded discrete interval is automatically
00089 // converted to a vector, which makes it possible to apply array
00090 // functions to it.
00091 // </synopsis> 
00092 
00093 class TableExprNodeSetElem : public TableExprNodeRep
00094 {
00095 public:
00096     // Create the object for a single expression node.
00097     explicit TableExprNodeSetElem (const TableExprNode& node);
00098 
00099     // Create the object for a discrete interval.
00100     // Each of the start, end, and incr pointers can be zero meaning
00101     // that they are not given (see the synopsis for an explanation).
00102     // Optionally the end is inclusive (C++ and Glish style) or exclusive
00103     // (Python style).
00104     TableExprNodeSetElem (const TableExprNode* start,
00105                           const TableExprNode* end,
00106                           const TableExprNode* incr,
00107                           Bool isEndExcl = False);
00108 
00109     // Create the object for a continuous bounded interval. It can be
00110     // open or closed on either side.
00111     TableExprNodeSetElem (Bool isLeftClosed, const TableExprNode& start,
00112                           const TableExprNode& end, Bool isRightClosed);
00113 
00114     // Create the object for a continuous left-bounded interval.
00115     TableExprNodeSetElem (Bool isLeftClosed, const TableExprNode& start);
00116 
00117     // Create the object for a continuous right-bounded interval.
00118     TableExprNodeSetElem (const TableExprNode& end, Bool isRightClosed);
00119 
00120     // Copy constructor (copy semantics).
00121     TableExprNodeSetElem (const TableExprNodeSetElem&);
00122 
00123     ~TableExprNodeSetElem();
00124 
00125     // Show the node.
00126     void show (ostream& os, uInt indent) const;
00127 
00128     // Get the nodes representing an aggregate function.
00129     virtual void getAggrNodes (vector<TableExprNodeRep*>& aggr);
00130   
00131     // Get the nodes representing a table column.
00132     virtual void getColumnNodes (vector<TableExprNodeRep*>& cols);
00133   
00134     // Is it a discrete set element.
00135     Bool isDiscrete() const;
00136 
00137     // Is a single value given?
00138     Bool isSingle() const;
00139 
00140     // Is the interval left or right closed?
00141     // <group>
00142     Bool isLeftClosed() const;
00143     Bool isRightClosed() const;
00144     // </group>
00145 
00146     // Get the start, end or increment expression.
00147     // Note that the pointer returned can be zero indicating that that
00148     // value was not given.
00149     // <group>
00150     TableExprNodeRep* start() const;
00151     TableExprNodeRep* end() const;
00152     TableExprNodeRep* increment() const;
00153     // </group>
00154 
00155     // Fill a vector with the value(s) from this element by appending them
00156     // at the end of the vector; the end is given by argument <src>cnt</src>
00157     // which gets incremented with the number of values appended.
00158     // This is used by the system to convert a set to a vector.
00159     // <group>
00160     void fillVector (Vector<Bool>& vec, Int64& cnt,
00161                      const TableExprId& id) const;
00162     void fillVector (Vector<Int64>& vec, Int64& cnt,
00163                      const TableExprId& id) const;
00164     void fillVector (Vector<Double>& vec, Int64& cnt,
00165                      const TableExprId& id) const;
00166     void fillVector (Vector<DComplex>& vec, Int64& cnt,
00167                      const TableExprId& id) const;
00168     void fillVector (Vector<String>& vec, Int64& cnt,
00169                      const TableExprId& id) const;
00170     void fillVector (Vector<MVTime>& vec, Int64& cnt,
00171                      const TableExprId& id) const;
00172     // </group>
00173 
00174     // Set a flag in the match output array if the corresponding element
00175     // in the value array is included in this set element.
00176     // This is used by the system to implement the IN operator.
00177     // <br>Note that it does NOT set match values to False; it is assumed they
00178     // are initialized that way.
00179     // <group>
00180     void matchBool     (Bool* match, const Bool* value, uInt nval,
00181                         const TableExprId& id) const;
00182     void matchInt      (Bool* match, const Int64* value, uInt nval,
00183                         const TableExprId& id) const;
00184     void matchDouble   (Bool* match, const Double* value, uInt nval,
00185                         const TableExprId& id) const;
00186     void matchDComplex (Bool* match, const DComplex* value, uInt nval,
00187                         const TableExprId& id) const;
00188     void matchString   (Bool* match, const String* value, uInt nval,
00189                         const TableExprId& id) const;
00190     void matchDate     (Bool* match, const MVTime* value, uInt nval,
00191                         const TableExprId& id) const;
00192     // </group>
00193 
00194     // Evaluate the element for the given row and construct a new
00195     // (constant) element from it.
00196     // This is used by the system to implement a set in a GIVING clause.
00197     TableExprNodeSetElem* evaluate (const TableExprId& id) const;
00198 
00199     // Get the table of a node and check if the children use the same table.
00200     void checkTable();
00201 
00202     // Let a set node convert itself to the given unit.
00203     virtual void adaptSetUnits (const Unit&);
00204 
00205 private:
00206     // A copy of a TableExprNodeSetElem cannot be made.
00207     TableExprNodeSetElem& operator= (const TableExprNodeSetElem&);
00208 
00209     // Construct an element from the given parts and take over their pointers.
00210     // It is used by evaluate to construct an element in a rather cheap way.
00211     TableExprNodeSetElem (const TableExprNodeSetElem& that,
00212                           TableExprNodeRep* start, TableExprNodeRep* end,
00213                           TableExprNodeRep* incr);
00214 
00215     // Setup the object for a continuous interval.
00216     void setup (Bool isLeftClosed, const TableExprNode* start,
00217                 const TableExprNode* end, Bool isRightClosed);
00218 
00219 
00220     TableExprNodeRep* itsStart;
00221     TableExprNodeRep* itsEnd;
00222     TableExprNodeRep* itsIncr;
00223     Bool itsEndExcl;
00224     Bool itsLeftClosed;
00225     Bool itsRightClosed;
00226     Bool itsDiscrete;
00227     Bool itsSingle;
00228 };
00229 
00230 
00231 
00232 inline Bool TableExprNodeSetElem::isDiscrete() const
00233 {
00234     return itsDiscrete;
00235 }
00236 inline Bool TableExprNodeSetElem::isSingle() const
00237 {
00238     return itsSingle;
00239 }
00240 inline Bool TableExprNodeSetElem::isLeftClosed() const
00241 {
00242     return itsLeftClosed;
00243 }
00244 inline Bool TableExprNodeSetElem::isRightClosed() const
00245 {
00246     return itsRightClosed;
00247 }
00248 inline TableExprNodeRep* TableExprNodeSetElem::start() const
00249 {
00250     return itsStart;
00251 }
00252 inline TableExprNodeRep* TableExprNodeSetElem::end() const
00253 {
00254     return itsEnd;
00255 }
00256 inline TableExprNodeRep* TableExprNodeSetElem::increment() const
00257 {
00258     return itsIncr;
00259 }
00260 
00261 
00262 
00263 // <summary>
00264 // Class to hold multiple table expression nodes.
00265 // </summary>
00266 
00267 // <use visibility=export>
00268 
00269 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00270 // </reviewed>
00271 
00272 // <prerequisite>
00273 //# Classes you should understand before using this one.
00274 //   <li> TableExprNode
00275 //   <li> TableExprNodeRep
00276 //   <li> TableExprNodeBinary
00277 // </prerequisite>
00278 
00279 // <synopsis> 
00280 // This class is used to assemble several table expression nodes.
00281 // It is used for 3 purposes:
00282 // <ol>
00283 // <li> To hold the arguments of a function.
00284 //      All set elements must be single.
00285 // <li> To hold the variables of an index for an array slice.
00286 //      All set elements must be of type int scalar and they must
00287 //      represent a discrete interval (which includes single).
00288 // <li> To hold the elements of a set used with the IN operator.
00289 //      All set elements must be scalars of any type.
00290 // </ol>
00291 // The type of all set elements has to be the same.
00292 // The set consists of
00293 // <linkto class=TableExprNodeSetElem>TableExprNodeSetElem</linkto>
00294 // elements. The <src>add</src> function has to be used to
00295 // add an element to the set.
00296 // <p>
00297 // It is possible to construct the object directly from an
00298 // <linkto class=IPosition>IPosition</linkto> object.
00299 // In that case all elements are single.
00300 // Furthermore it is possible to construct it directly from a
00301 // <linkto class=Slicer>Slicer</linkto> object.
00302 // In that case all elements represent a discrete interval.
00303 // </synopsis> 
00304 
00305 class TableExprNodeSet : public TableExprNodeRep
00306 {
00307 public:
00308     // Construct an empty set.
00309     TableExprNodeSet();
00310 
00311     // Construct from an <src>IPosition</src>.
00312     // The number of elements in the set is the number of elements
00313     // in the <src>IPosition</src>. All set elements are single values.
00314     TableExprNodeSet (const IPosition&);
00315 
00316     // Construct from a <src>Slicer</src>.
00317     // The number of elements in the set is the dimensionality
00318     // of the <src>Slicer</src>. All set elements are discrete intervals.
00319     // Their start and/or end is undefined if it is was not defined
00320     // (i.e. Slicer::MimicSource used) in the <src>Slicer</src> object.
00321     TableExprNodeSet (const Slicer&);
00322 
00323     // Construct a set with n*set.nelements() elements where n is the number
00324     // of rows.
00325     // Element i is constructed by evaluating the input element
00326     // for row rownr[i].
00327     TableExprNodeSet (const Vector<uInt>& rownrs, const TableExprNodeSet&);
00328 
00329     TableExprNodeSet(const TableExprNodeSet&);
00330 
00331     ~TableExprNodeSet();
00332     
00333     // Add an element to the set.
00334     // If adaptType=True, the data type is the highest of the elements added.
00335     // Otherwise it is that of the first element.
00336     // True is meant for a set of values, False for function arguments.
00337     void add (const TableExprNodeSetElem&, Bool adaptType=False);
00338 
00339     // Show the node.
00340     void show (ostream& os, uInt indent) const;
00341 
00342     // Get the nodes representing an aggregate function.
00343     virtual void getAggrNodes (vector<TableExprNodeRep*>& aggr);
00344   
00345     // Get the nodes representing a table column.
00346     virtual void getColumnNodes (vector<TableExprNodeRep*>& cols);
00347   
00348     // Check if the data type of the set elements are the same.
00349     // If not, an exception is thrown.
00350     //# Note that if itsCheckTypes is set, the data types are already
00351     //# known to be equal.
00352     void checkEqualDataTypes() const;
00353 
00354     // Contains the set only single elements?
00355     // Single means that only single values are given (thus end nor incr).
00356     Bool isSingle() const;
00357 
00358     // Contains the set only discrete elements?
00359     // Discrete means that no continuous ranges are given, but discrete
00360     // ranges (using :) are possible.
00361     Bool isDiscrete() const;
00362 
00363     // Is the set fully bounded (discrete and no undefined end values)?
00364     Bool isBounded() const;
00365 
00366     // Get the number of elements.
00367     uInt nelements() const;
00368 
00369     // Get the i-th element.
00370     const TableExprNodeSetElem& operator[] (uInt index) const;
00371 
00372     // Contains the set array values?
00373     Bool hasArrays() const;
00374 
00375     // Try to convert the set to an array.
00376     // If not possible, a copy of the set is returned.
00377     TableExprNodeRep* setOrArray() const;
00378 
00379     template<typename T>
00380     MArray<T> toArray (const TableExprId& id) const;
00381 
00382     // Get an array value for this bounded set in the given row.
00383     // <group>
00384     virtual MArray<Bool> getArrayBool         (const TableExprId& id);
00385     virtual MArray<Int64> getArrayInt         (const TableExprId& id);
00386     virtual MArray<Double> getArrayDouble     (const TableExprId& id);
00387     virtual MArray<DComplex> getArrayDComplex (const TableExprId& id);
00388     virtual MArray<String> getArrayString     (const TableExprId& id);
00389     virtual MArray<MVTime> getArrayDate       (const TableExprId& id);
00390     // </group>
00391 
00392     // Does a value occur in the set?
00393     // <group>
00394     virtual Bool hasBool     (const TableExprId& id, Bool value);
00395     virtual Bool hasInt      (const TableExprId& id, Int64 value);
00396     virtual Bool hasDouble   (const TableExprId& id, Double value);
00397     virtual Bool hasDComplex (const TableExprId& id, const DComplex& value);
00398     virtual Bool hasString   (const TableExprId& id, const String& value);
00399     virtual Bool hasDate     (const TableExprId& id, const MVTime& value);
00400     virtual MArray<Bool> hasArrayBool     (const TableExprId& id,
00401                                            const MArray<Bool>& value);
00402     virtual MArray<Bool> hasArrayInt      (const TableExprId& id,
00403                                            const MArray<Int64>& value);
00404     virtual MArray<Bool> hasArrayDouble   (const TableExprId& id,
00405                                            const MArray<Double>& value);
00406     virtual MArray<Bool> hasArrayDComplex (const TableExprId& id,
00407                                            const MArray<DComplex>& value);
00408     virtual MArray<Bool> hasArrayString   (const TableExprId& id,
00409                                            const MArray<String>& value);
00410     virtual MArray<Bool> hasArrayDate     (const TableExprId& id,
00411                                            const MArray<MVTime>& value);
00412     // </group>
00413 
00414     // Let a set node convert itself to the given unit.
00415     virtual void adaptSetUnits (const Unit&);
00416 
00417 private:
00418     // A copy of a TableExprNodeSet cannot be made.
00419     TableExprNodeSet& operator= (const TableExprNodeSet&);
00420 
00421     // Delete all set elements in itsElems.
00422     void deleteElems();
00423 
00424     // Convert the const set to an array.
00425     TableExprNodeRep* toConstArray() const;
00426 
00427     // Get the array in a templated way.
00428     // <group>
00429     void getArray (MArray<Bool>& marr, TableExprNodeRep* node,
00430                            const TableExprId& id) const
00431       { marr.reference (node->getArrayBool (id)); }
00432     void getArray (MArray<Int64>& marr, TableExprNodeRep* node,
00433                             const TableExprId& id) const
00434       { marr.reference (node->getArrayInt (id)); }
00435     void getArray (MArray<Double>& marr, TableExprNodeRep* node,
00436                              const TableExprId& id) const
00437       { marr.reference (node->getArrayDouble (id)); }
00438     void getArray (MArray<DComplex>& marr, TableExprNodeRep* node,
00439                                const TableExprId& id) const
00440       { marr.reference (node->getArrayDComplex (id)); }
00441     void getArray (MArray<String>& marr, TableExprNodeRep* node,
00442                              const TableExprId& id) const
00443       { marr.reference (node->getArrayString (id)); }
00444     void getArray (MArray<MVTime>& marr, TableExprNodeRep* node,
00445                              const TableExprId& id) const
00446       { marr.reference (node->getArrayDate (id)); }
00447     // </group>
00448 
00449     // Sort and combine intervals.
00450     // <group>
00451     void combineIntIntervals();
00452     void combineDoubleIntervals();
00453     void combineDateIntervals();
00454     // </group>
00455 
00456     // Define the functions to find a double, which depend on open/closed-ness.
00457     // In this way a test on open/closed is done only once.
00458     // <group>
00459     typedef Bool (TableExprNodeSet::* FindFuncPtr) (Double value);
00460     Bool findOpenOpen     (Double value);
00461     Bool findOpenClosed   (Double value);
00462     Bool findClosedOpen   (Double value);
00463     Bool findClosedClosed (Double value);
00464     void setFindFunc (Bool isLeftClosed, Bool isRightClosed);
00465     // </group>
00466 
00467     PtrBlock<TableExprNodeSetElem*> itsElems;
00468     Bool itsSingle;
00469     Bool itsDiscrete;
00470     Bool itsBounded;       //# Set is discrete and all starts/ends are defined
00471     Bool itsCheckTypes;    //# True = checking data types is not needed
00472     Bool itsAllIntervals;  //# True = all elements are const intervals (sorted)
00473     Block<Double> itsStart; //# Start values of const intervals
00474     Block<Double> itsEnd;   //# End values of const intervals
00475     FindFuncPtr   itsFindFunc; //# Function to find a matching const interval
00476 };
00477 
00478 
00479 inline Bool TableExprNodeSet::isSingle() const
00480 {
00481     return itsSingle;
00482 }
00483 inline Bool TableExprNodeSet::isDiscrete() const
00484 {
00485     return itsDiscrete;
00486 }
00487 inline Bool TableExprNodeSet::isBounded() const
00488 {
00489     return itsBounded;
00490 }
00491 inline uInt TableExprNodeSet::nelements() const
00492 {
00493     return itsElems.nelements();
00494 }
00495 inline const TableExprNodeSetElem&
00496                            TableExprNodeSet::operator[] (uInt index) const
00497 {
00498     return *(itsElems[index]);
00499 }
00500 
00501 
00502 template<typename T>
00503 MArray<T> TableExprNodeSet::toArray (const TableExprId& id) const
00504 {
00505   // TODO: align possible units
00506     DebugAssert (itsBounded, AipsError);
00507     Int64 n = nelements();
00508     if (hasArrays()) {
00509       // Handle a nested array; this is done recursively.
00510       MArray<T> marr;
00511       getArray (marr, itsElems[0]->start(), id);
00512       if (marr.isNull()) return marr;
00513       Array<T> result (marr.array());
00514       Array<Bool> mask (marr.mask());
00515       IPosition shp = result.shape();
00516       uInt naxes = shp.size();
00517       shp.append (IPosition(1,n));
00518       result.resize (shp, True);
00519       if (! mask.empty()) mask.resize (shp, True);
00520       ArrayIterator<T> iter(result, shp.size()-1);
00521       IPosition s(shp);
00522       IPosition e(shp);
00523       s[naxes] = 0;
00524       e[naxes] = 0;
00525       for (Int64 i=1; i<n; i++) {
00526         iter.next();
00527         s[naxes]++;
00528         e[naxes]++;
00529         MArray<T> marr;
00530         getArray (marr, itsElems[i]->start(), id);
00531         if (marr.isNull()) return marr;
00532         if (! marr.shape().isEqual (iter.array().shape())) {
00533           throw TableInvExpr("Shapes of nested arrays do not match");
00534         }
00535         iter.array() = marr.array();
00536         if (marr.hasMask()) {
00537           if (mask.empty()) {
00538             mask.resize (shp);
00539             mask = False;
00540           }
00541           mask(s,e) = marr.mask();
00542         } else if (! mask.empty()) {
00543           mask(s,e) = False;
00544         }
00545       }
00546       return MArray<T>(result, mask);
00547     } else {
00548       Int64 n = nelements();
00549       Int64 cnt = 0;
00550       Vector<T> result (n);
00551       for (Int64 i=0; i<n; i++) {
00552         itsElems[i]->fillVector (result, cnt, id);
00553       }
00554       result.resize (cnt, True);
00555       return MArray<T>(result);
00556     }
00557 }
00558 
00559 
00560 
00561 } //# NAMESPACE CASACORE - END
00562 
00563 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1