casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
PlotData.h
Go to the documentation of this file.
00001 //# PlotData.h: Classes to represent data for plots.
00002 //# Copyright (C) 2008
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: $
00027 #ifndef PLOTDATA_H_
00028 #define PLOTDATA_H_
00029 
00030 #include <graphics/GenericPlotter/PlotOptions.h>
00031 
00032 #include <casa/Arrays/Matrix.h>
00033 #include <casa/Arrays/Vector.h>
00034 
00035 #include <casa/BasicSL/String.h>
00036 #include <casa/Utilities/CountedPtr.h>
00037 
00038 #include <casa/namespace.h>
00039 using namespace std;
00040 
00041 namespace casa {
00042 
00043 // Typedef for a point, which is two doubles (x and y).
00044 typedef pair<double, double> ppoint_t;
00045 
00047 // ABSTRACT CLASSES //
00049 
00050 // Deliberately vague to be general enough to allow for many different types
00051 // of data, but is it too vague to be useful?  Since the interface is meant
00052 // to be a simple plotter, it may be better to restrict PlotData to be more
00053 // like PlotPointData, which would eliminate possibilities for data like
00054 // functions but would also eliminate a lot of vaguery.
00055 class PlotData {
00056 public:
00057     PlotData() { }
00058     
00059     virtual ~PlotData() { }
00060     
00061     
00062     // ABSTRACT METHODS //
00063     
00064     // Returns whether the contained data is valid or not.
00065     virtual bool isValid() const = 0;
00066     
00067     // Returns whether this object will delete its underlying data structures
00068     // upon deconstruction or not.
00069     virtual bool willDeleteData() const = 0;
00070     
00071     // Sets whether this object will delete its underlying data structures upon
00072     // deconstruction or not.
00073     virtual void setDeleteData(bool del = true) = 0;
00074 };
00075 typedef CountedPtr<PlotData> PlotDataPtr;
00076 
00077 
00078 // A single source of data that basically provides indexing of its values.
00079 class PlotSingleData : public virtual PlotData {
00080 public:
00081     PlotSingleData() { }
00082     
00083     virtual ~PlotSingleData() { }
00084     
00085     
00086     // ABSTRACT METHODS //
00087     
00088     // Returns the number of points.
00089     virtual unsigned int size() const = 0;
00090     
00091     // Returns the value at given index.
00092     virtual double at(unsigned int i) const = 0;
00093     
00094     // Gets the minimum and maximum values.  Returns false for error.
00095     virtual bool minMax(double& min, double& max) = 0;
00096 };
00097 INHERITANCE_POINTER2(PlotSingleData, PlotSingleDataPtr, PlotData, PlotDataPtr)
00098 
00099 
00100 // A source of data used to supply x and y values.  Basically consists of
00101 // indexing its values.
00102 class PlotPointData : public virtual PlotData {
00103 public:
00104     PlotPointData() { }
00105     
00106     virtual ~PlotPointData() { }
00107     
00108     
00109     // ABSTRACT METHODS //
00110     
00111     // Returns the number of points.
00112     virtual unsigned int size() const = 0;
00113     
00114     // Returns the x value at the given index.
00115     virtual double xAt(unsigned int i) const = 0;
00116     
00117     // Returns the y value at the given index.
00118     virtual double yAt(unsigned int i) const = 0;
00119     
00120     // Gets the minimum and maximum values.  Returns false for error.
00121     virtual bool minsMaxes(double& xMin, double& xMax, double& yMin,
00122                            double& yMax) = 0;
00123     
00124     
00125     // IMPLEMENTED METHODS //
00126     
00127     // Gets the x and y values at the given index.  Default implementation
00128     // just calls xAt and yAt, but in subclasses where performance could be
00129     // gained, this method should be overridden.  Implementations for plots
00130     // that use PlotPointData should use this method by default in case there
00131     // are performance gains.
00132     virtual void xAndYAt(unsigned int index, double& x, double& y) const;
00133 };
00134 INHERITANCE_POINTER2(PlotPointData, PlotPointDataPtr, PlotData, PlotDataPtr)
00135 
00136 
00137 // Data that adds masking functionality on top of normal point data.
00138 class PlotMaskedPointData : public virtual PlotPointData {
00139 public:
00140     PlotMaskedPointData() { }
00141     
00142     virtual ~PlotMaskedPointData() { }
00143     
00144     
00145     // ABSTRACT METHODS //
00146     
00147     // Returns the number of masked points.
00148     virtual unsigned int sizeMasked() const = 0;
00149     
00150     // Returns the number of unmasked points.
00151     virtual unsigned int sizeUnmasked() const = 0;
00152     
00153     // Returns whether the data is masked at the given point or not.
00154     virtual bool maskedAt(unsigned int index) const = 0;
00155     
00156     // Gets the mins/maxes for just the masked points.
00157     virtual bool maskedMinsMaxes(double& xMin, double& xMax, double& yMin,
00158                                  double& yMax) = 0;
00159     
00160     // Gets the mins/maxes for just the unmasked points.
00161     virtual bool unmaskedMinsMaxes(double& xMin, double& xMax, double& yMin,
00162                                    double& yMax) = 0;
00163     
00164     
00165     // IMPLEMENTED METHODS //
00166     
00167     // Gets the x and y values and the mask at the given index.  See
00168     // PlotPointData::xAndYAt().
00169     virtual void xyAndMaskAt(unsigned int index, double& x, double& y,
00170                              bool& mask) const;
00171 };
00172 INHERITANCE_POINTER(PlotMaskedPointData, PlotMaskedPointDataPtr, PlotPointData,
00173                     PlotPointDataPtr, PlotData, PlotDataPtr)
00174 
00175 
00176 // Data that adds error functionality on top of normal plot data.
00177 class PlotErrorData : public virtual PlotPointData {
00178 public:
00179     PlotErrorData() { }
00180     
00181     virtual ~PlotErrorData() { }    
00182     
00183     
00184     // ABSTRACT METHODS //
00185     
00186     // Returns the "left" error for x at the given index.
00187     virtual double xLeftErrorAt(unsigned int i) const = 0;
00188     
00189     // Returns the "right" error for x at the given index.
00190     virtual double xRightErrorAt(unsigned int i) const = 0;
00191     
00192     // Returns the "bottom" error for y at the given index.
00193     virtual double yBottomErrorAt(unsigned int i) const = 0;
00194     
00195     // Returns the "top" error for y at the given index.
00196     virtual double yTopErrorAt(unsigned int i) const = 0;
00197     
00198     // Gets the maximum errors for the four sides.
00199     virtual bool errorMaxes(double& xLeft, double& xRight, double& yBottom,
00200                             double& yTop) = 0;
00201     
00202     
00203     // IMPLEMENTED METHODS //
00204     
00205     // Gets the x and y values and error data at the given index.  See
00206     // PlotPointData::xAndYAt().
00207     virtual void xyAndErrorsAt(unsigned int index, double& x, double& y,
00208             double& xLeftError, double& xRightError, double& yBottomError,
00209             double& yTopError) const;
00210 };
00211 INHERITANCE_POINTER(PlotErrorData, PlotErrorDataPtr, PlotPointData,
00212                     PlotDataPtr, PlotData, PlotDataPtr)
00213 
00214 
00215 // Data that differentiates different points into different "bins" on top of
00216 // normal point data functionality.
00217 class PlotBinnedData : public virtual PlotPointData {
00218 public:
00219     // Constructor.
00220     PlotBinnedData() { }
00221     
00222     // Destructor.
00223     virtual ~PlotBinnedData() { }    
00224     
00225     
00226     // ABSTRACT METHODS //
00227     
00228     // Returns the total number of bins that the data is in.
00229     virtual unsigned int numBins() const = 0;
00230     
00231     // Returns the bin index number for the given index.  MUST be between 0 and
00232     // numBins().
00233     virtual unsigned int binAt(unsigned int i) const = 0;
00234     
00235     
00236     // IMPLEMENTED METHODS //
00237     
00238     // Returns true if the data is binned, false otherwise.
00239     virtual bool isBinned() const { return numBins() > 1; }
00240 };
00241 INHERITANCE_POINTER(PlotBinnedData, PlotBinnedDataPtr, PlotPointData,
00242                     PlotDataPtr, PlotData, PlotDataPtr)
00243 
00244 
00245 // Data for raster plots, which can be thought of as three-dimensional.  Used
00246 // for images, with the values being in one of the givne formats.
00247 class PlotRasterData : public virtual PlotData {
00248 public:
00249     // Format that the data is in
00250     enum Format {
00251         RGB32,       // data is an RBG integer, like 0x60A0C0
00252         ARGB32,      // data is an ARGB integer, like 0xFF60A0C0
00253         SPECTROGRAM  // data is meant for a spectrogram, not specific colors
00254     };
00255     
00256     // Origin point of the data - in other words, where (0,0) is located
00257     // visually on the canvas.  Default is LLEFT.
00258     enum Origin {
00259         LLEFT, LRIGHT, ULEFT, URIGHT
00260     };
00261     
00262     
00263     PlotRasterData() { }
00264     
00265     virtual ~PlotRasterData() { }
00266     
00267     
00268     // ABSTRACT METHODS //
00269     
00270     // Returns the data origin.
00271     virtual Origin origin() const = 0;
00272     
00273     // Sets the data origin.
00274     virtual void setOrigin(Origin o) = 0;
00275     
00276     // Returns the range of x.
00277     virtual prange_t xRange() const = 0;
00278     
00279     // Returns the range of y.
00280     virtual prange_t yRange() const = 0;    
00281     
00282     // Sets the range of x.
00283     virtual void setXRange(double from, double to) = 0;
00284     
00285     // Sets the range of y.
00286     virtual void setYRange(double from, double to) = 0;
00287     
00288     // Returns the range of the data values.
00289     virtual prange_t valueRange() const = 0;
00290     
00291     // Returns the data value at the given (x,y) coordinate.
00292     virtual double valueAt(double x, double y) const = 0;
00293     
00294     // Gets color bar values.
00295     virtual vector<double>* colorBarValues(unsigned int max = 1000) const = 0;
00296 };
00297 INHERITANCE_POINTER2(PlotRasterData, PlotRasterDataPtr, PlotData, PlotDataPtr)
00298 
00299 
00300 
00301 // DEFAULT IMPLEMENTATIONS //
00303 
00304 // Default implementation of PlotSingleData that supports raw arrays, vectors,
00305 // and CASA Vectors.  The class is templated, but since data sources are
00306 // expected in doubles it should be a numeric type that can be casted to a
00307 // double.
00308 template <class T>
00309 class PlotSingleDataImpl : public virtual PlotSingleData {
00310 public:
00311     // Invalid data constructor.
00312     PlotSingleDataImpl(): m_vector(NULL), m_cvector(NULL), m_array(NULL),
00313             m_arraySize(0), m_shouldDelete(false) { }
00314     
00315     // Data using different standard containers.
00316     // <group>
00317     PlotSingleDataImpl(vector<T>& value, bool shouldDelete = false):
00318             m_vector(&value), m_cvector(NULL), m_array(NULL), m_arraySize(0),
00319             m_shouldDelete(shouldDelete) {
00320         recalculateMinMax(); }
00321     PlotSingleDataImpl(Vector<T>& value, bool shouldDelete = false):
00322             m_vector(NULL), m_cvector(&value), m_array(NULL), m_arraySize(0),
00323             m_shouldDelete(shouldDelete) {
00324         recalculateMinMax(); }
00325     PlotSingleDataImpl(T*& value, unsigned int size, bool shouldDelete= false):
00326             m_vector(NULL), m_cvector(NULL), m_array(value), m_arraySize(size),
00327             m_shouldDelete(shouldDelete) {
00328         recalculateMinMax(); }
00329     // </group>
00330     
00331     // Destructor.
00332     ~PlotSingleDataImpl() {
00333         if(m_shouldDelete) {
00334             if(m_vector != NULL) delete m_vector;
00335             if(m_cvector != NULL) delete m_cvector;
00336             if(m_array != NULL) delete m_array;
00337         }
00338     }
00339     
00340     
00341     // Implements PlotData::isValid().
00342     bool isValid() const {
00343         return m_vector != NULL || m_cvector != NULL || m_array != NULL; }
00344 
00345     // Implements PlotData::willDeleteData().
00346     bool willDeleteData() const { return m_shouldDelete; }
00347 
00348     // Implements PlotData::setDeleteData().
00349     void setDeleteData(bool del = true) { m_shouldDelete = del; }
00350     
00351     // Implements PlotSingleData::size().
00352     unsigned int size() const {
00353         if(m_vector != NULL) return m_vector->size();
00354         if(m_cvector != NULL) return m_cvector->size();
00355         if(m_array != NULL) return m_arraySize;
00356         return 0;
00357     }
00358 
00359     // Implements PlotSingleData::at().
00360     double at(unsigned int i) const {
00361         if(m_vector != NULL) return (double)(*m_vector)[i];
00362         if(m_cvector != NULL) return (double)(*m_cvector)[i];
00363         if(m_array != NULL) return (double)m_array[i];
00364         return 0;
00365     }
00366 
00367     // Implements PlotSingleData::minMax().
00368     bool minMax(double& min, double& max) {
00369         if(!isValid() || size() == 0) return false;
00370         min = m_min; max = m_max;
00371         return true;
00372     }
00373     
00374     // Recalculates the cached min and max.  Should be used if the underlying
00375     // data structure changes.
00376     void recalculateMinMax() {
00377         if(!isValid()) return;
00378         unsigned int n = size();
00379         if(n == 0) return;
00380         double temp = (double)at(0);
00381         m_min = m_max = temp;
00382         if(m_vector != NULL) {
00383             for(unsigned int i = 1; i < n; i++) {
00384                 temp = (double)(*m_vector)[i];
00385                 if(temp < m_min) m_min = temp;
00386                 if(temp > m_max) m_max = temp;
00387             }
00388         } else if(m_cvector != NULL) {
00389             for(unsigned int i = 1; i < n; i++) {
00390                 temp = (double)(*m_cvector)[i];
00391                 if(temp < m_min) m_min = temp;
00392                 if(temp > m_max) m_max = temp;
00393             }
00394         } else if(m_array != NULL) {
00395             for(unsigned int i = 1; i < n; i++) {
00396                 temp = (double)m_array[i];
00397                 if(temp < m_min) m_min = temp;
00398                 if(temp > m_max) m_max = temp;
00399             }
00400         }
00401     }
00402     
00403 private:
00404     vector<T>* m_vector;
00405     Vector<T>* m_cvector;
00406     T* m_array;
00407     unsigned int m_arraySize;
00408     bool m_shouldDelete;
00409     double m_min, m_max;
00410 };
00411 
00412 typedef PlotSingleDataImpl<int> PlotSingleIntData;
00413 typedef PlotSingleDataImpl<unsigned int> PlotSingleUIntData;
00414 typedef PlotSingleDataImpl<float> PlotSingleFloatData;
00415 typedef PlotSingleDataImpl<double> PlotSingleDoubleData;
00416 
00417 
00418 // Default implementation of PlotPointData that supports raw arrays, vectors,
00419 // and CASA Vectors.  The class is templated, but since data sources are
00420 // expected in doubles it should be a numeric type that can be casted to a
00421 // double.  It can either be both x and y data, or just y data (where x is the
00422 // index).
00423 template <class T>
00424 class PlotPointDataImpl : public virtual PlotPointData {
00425 public:
00426     // X/Y constructors.
00427     // <group>
00428     PlotPointDataImpl(vector<T>& x, vector<T>& y, bool shouldDelete = false) :
00429             m_xData(x, shouldDelete), m_yData(y, shouldDelete) { }
00430     PlotPointDataImpl(Vector<T>& x, Vector<T>& y, bool shouldDelete = false) :
00431             m_xData(x, shouldDelete), m_yData(y, shouldDelete) { }
00432     PlotPointDataImpl(T*& x, T*& y, unsigned int size, bool shouldDel = false):
00433             m_xData(x, size, shouldDel), m_yData(y, size, shouldDel) { }
00434     // </group>
00435     
00436     // Y constructors.
00437     // <group>
00438     PlotPointDataImpl(vector<T>& y, bool shouldDelete = false) :
00439             m_yData(y, shouldDelete) { }
00440     PlotPointDataImpl(Vector<T>& y, bool shouldDelete = false) :
00441             m_yData(y, shouldDelete) { }
00442     PlotPointDataImpl(T*& y, unsigned int size, bool shouldDel = false):
00443             m_yData(y, size, shouldDel) { }
00444     // </group>
00445     
00446     virtual ~PlotPointDataImpl() { }
00447     
00448     
00449     // Implements PlotData::isValid().
00450     bool isValid() const { return m_yData.isValid(); }
00451 
00452     // Implements PlotData::willDeleteData().
00453     virtual bool willDeleteData() const { 
00454         return (m_yData.isValid() && m_yData.willDeleteData()) &&
00455                (!m_xData.isValid() || m_xData.willDeleteData());
00456     }
00457 
00458     // Implements PlotData::setDeleteData().
00459     virtual void setDeleteData(bool del = true) {
00460         if(m_xData.isValid()) m_xData.setDeleteData(del);
00461         if(m_yData.isValid()) m_yData.setDeleteData(del);
00462     }
00463     
00464     // Implements PlotPointData::size().
00465     unsigned int size() const {
00466         if(!m_xData.isValid()) return m_yData.size();
00467         else return min(m_xData.size(), m_yData.size());
00468     }
00469 
00470     // Implements PlotPointData::xAt().  If no x data is given, the index is
00471     // returned.
00472     double xAt(unsigned int i) const {
00473         if(m_xData.isValid()) return m_xData.at(i);
00474         else                  return i;
00475     }
00476 
00477     // Implements PlotPointData::yAt().
00478     double yAt(unsigned int i) const { return m_yData.at(i); }
00479 
00480     // Implements PlotPointData::minsMaxes().
00481     bool minsMaxes(double& xMin, double& xMax, double& yMin, double& yMax) {
00482         if(!m_xData.isValid()) {
00483             xMin = 0;
00484             xMax = m_yData.size();
00485             return m_yData.minMax(yMin, yMax);
00486         } else {
00487             return m_xData.minMax(xMin, xMax) && m_yData.minMax(yMin, yMax);
00488         }
00489     }
00490     
00491 private:
00492     PlotSingleDataImpl<T> m_xData;
00493     PlotSingleDataImpl<T> m_yData;
00494 };
00495 
00496 typedef PlotPointDataImpl<int> PlotPointIntData;
00497 typedef PlotPointDataImpl<unsigned int> PlotPointUIntData;
00498 typedef PlotPointDataImpl<float> PlotPointFloatData;
00499 typedef PlotPointDataImpl<double> PlotPointDoubleData;
00500 
00501 
00502 // Specialized subclass of PlotPointData that creates histogram data from
00503 // single point data.  A histogram divides up the data into a number of "bins"
00504 // and then counts the number of data that falls into each bin.  This class can
00505 // act as both an interface for specializations or a concrete subclass of
00506 // PlotPointData in itself.
00507 class PlotHistogramData : public virtual PlotPointData {
00508 public:    
00509     // Constructor which takes data and number of bins.
00510     PlotHistogramData(PlotSingleDataPtr data, unsigned int numBins);
00511     
00512     // Destructor.
00513     virtual ~PlotHistogramData();
00514     
00515     
00516     // Implements PlotData::isValid().
00517     virtual bool isValid() const;
00518     
00519     // Implements PlotData::willDeleteData().
00520     virtual bool willDeleteData() const;
00521     
00522     // Implements PlotData::setDeleteData().
00523     virtual void setDeleteData(bool del = true);
00524     
00525     
00526     // Implements PlotPointData::size().
00527     virtual unsigned int size() const { return numBins(); }
00528     
00529     // Implements PlotPointData::xAt().
00530     virtual double xAt(unsigned int i) const;
00531     
00532     // Implements PlotPointData::yAt().
00533     virtual double yAt(unsigned int i) const;
00534     
00535     // Implements PlotPointData::minsMaxes().
00536     virtual bool minsMaxes(double& xMin, double& xMax, double& yMin,
00537                            double& yMax);
00538     
00539     
00540     // Recalculates the histogram data into the given number of bins.
00541     virtual void recalculateBins(unsigned int numBins);
00542     
00543     // Returns the current number of histogram bins.
00544     virtual unsigned int numBins() const;
00545     
00546     // Returns the range at the given index.
00547     virtual prange_t rangeAt(unsigned int i) const;
00548     
00549 private:
00550     PlotSingleDataPtr m_data;    // Data.
00551     vector<unsigned int> m_bins; // Bins with count.
00552     vector<prange_t> m_ranges;   // Cached bin ranges.
00553     unsigned int m_max;          // Highest bin count.
00554 };
00555 
00556 
00557 // Default implementation of PlotMaskedPointData using default containers.
00558 template <class T>
00559 class PlotMaskedPointDataImpl : public virtual PlotMaskedPointData,
00560                                 public PlotPointDataImpl<T> {
00561 public:
00562     // X/Y constructors.
00563     // <group>
00564     PlotMaskedPointDataImpl(vector<T>& x, vector<T>& y, vector<bool>& mask,
00565             bool shouldDelete = false) :
00566             PlotPointDataImpl<T>(x, y, shouldDelete), m_maskVector(&mask),
00567             m_maskCVector(NULL), m_maskArray(NULL), m_maskArraySize(0),
00568             m_shouldDeleteMask(shouldDelete) { }
00569     PlotMaskedPointDataImpl(Vector<T>& x, Vector<T>& y, Vector<bool>& mask,
00570             bool shouldDelete = false) :
00571             PlotPointDataImpl<T>(x, y, shouldDelete), m_maskVector(NULL),
00572             m_maskCVector(&mask), m_maskArray(NULL), m_maskArraySize(0),
00573             m_shouldDeleteMask(shouldDelete) { }
00574     PlotMaskedPointDataImpl(T*& x, T*& y, bool*& mask, unsigned int size,
00575             bool shouldDel = false) :
00576             PlotPointDataImpl<T>(x, y, size, shouldDel), m_maskVector(NULL),
00577             m_maskCVector(NULL), m_maskArray(mask), m_maskArraySize(size),
00578             m_shouldDeleteMask(shouldDel) { }
00579     // </group>
00580     
00581     // Y constructors.
00582     // <group>
00583     PlotMaskedPointDataImpl(vector<T>& y, vector<bool>& mask,
00584             bool shouldDelete = false) :
00585             PlotPointDataImpl<T>(y, shouldDelete), m_maskVector(&mask),
00586             m_maskCVector(NULL), m_maskArray(NULL), m_maskArraySize(0),
00587             m_shouldDeleteMask(shouldDelete) { }
00588     PlotMaskedPointDataImpl(Vector<T>& y, Vector<bool>& mask,
00589             bool shouldDelete = false) :
00590             PlotPointDataImpl<T>(y, shouldDelete), m_maskVector(NULL),
00591             m_maskCVector(&mask), m_maskArray(NULL), m_maskArraySize(0),
00592             m_shouldDeleteMask(shouldDelete) { }
00593     PlotMaskedPointDataImpl(T*& y, bool*& mask, unsigned int size,
00594             bool shouldDel = false) :
00595             PlotPointDataImpl<T>(y, size, shouldDel), m_maskVector(NULL),
00596             m_maskCVector(NULL), m_maskArray(mask), m_maskArraySize(size),
00597             m_shouldDeleteMask(shouldDel) { }
00598     // </group>
00599     
00600     // Destructor.
00601     ~PlotMaskedPointDataImpl() {
00602         if(m_shouldDeleteMask) {
00603             if(m_maskVector != NULL) delete m_maskVector;
00604             if(m_maskCVector != NULL) delete m_maskCVector;
00605             if(m_maskArray != NULL) delete m_maskArray;
00606         }
00607     }
00608     
00609     // Overrides PlotPointDataImpl::willDeleteData().
00610     bool willDeleteData() const {
00611         return PlotPointDataImpl<T>::willDeleteData() && m_shouldDeleteMask; }
00612 
00613     // Overrides PlotPointDataImpl::setDeleteData().
00614     void setDeleteData(bool del = true) {
00615         PlotPointDataImpl<T>::setDeleteData(del);
00616         m_shouldDeleteMask = del;
00617     }
00618    
00619     // Implements PlotMaskedPointData::sizeMasked().
00620     unsigned int sizeMasked() const { return sizeMaskedOrUnmasked(true); }
00621     
00622     // Implements PlotMaskedPointData::sizeUnmasked().
00623     unsigned int sizeUnmasked() const { return sizeMaskedOrUnmasked(false); }
00624     
00625     // Implements PlotMaskedPointData::maskedAt().
00626     bool maskedAt(unsigned int index) const {
00627         if(m_maskVector != NULL)  return (*m_maskVector)[index];
00628         if(m_maskCVector != NULL) return (*m_maskCVector)[index];
00629         if(m_maskArray != NULL)   return m_maskArray[index];
00630         return false;
00631     }
00632     
00633     // Implements PlotMaskedPointData::maskedMinsMaxes().
00634     bool maskedMinsMaxes(double& xMin, double& xMax, double& yMin,
00635                             double& yMax) {
00636         return getMaskedOrUnmaskedMinsMaxes(xMin, xMax, yMin, yMax, true); }
00637     
00638     // Implements PlotMaskedPointData::unmaskedMinsMaxes().
00639     bool unmaskedMinsMaxes(double& xMin, double& xMax, double& yMin,
00640                             double& yMax) {
00641         return getMaskedOrUnmaskedMinsMaxes(xMin, xMax, yMin, yMax, false); }
00642     
00643 private:
00644     vector<bool>* m_maskVector;
00645     Vector<bool>* m_maskCVector;
00646     bool* m_maskArray;
00647     unsigned int m_maskArraySize;
00648     bool m_shouldDeleteMask;
00649     
00650     // Helper for size.
00651     unsigned int sizeMaskedOrUnmasked(bool masked) const {
00652         unsigned int n = size();
00653         unsigned int count = 0;
00654         if(m_maskArray != NULL) {
00655             for(unsigned int i = 0; i < m_maskArraySize; i++)
00656                 if(m_maskArray[i]) count++;
00657         } else if(m_maskVector != NULL) {
00658             for(unsigned int i = 0; i < m_maskVector->size(); i++)
00659                 if((*m_maskVector)[i]) count++;
00660         } else if(m_maskCVector != NULL) {
00661             for(unsigned int i = 0; i < m_maskCVector->size(); i++)
00662                 if((*m_maskCVector)[i]) count++;
00663         } else return n;
00664         if(masked) return min(count, n);
00665         else       return min(n - count, n);
00666     }
00667     
00668     // Helper for mins/maxes.
00669     bool getMaskedOrUnmaskedMinsMaxes(double& xMin, double& xMax, double& yMin,
00670                                       double& yMax, bool masked) {
00671         if(!isValid()) return false;
00672         unsigned int n = size();
00673         if(n == 0) return false;
00674         if(m_maskArray == NULL && m_maskVector == NULL &&
00675            m_maskCVector == NULL) return minsMaxes(xMin, xMax, yMin, yMax);
00676         
00677         unsigned int i = 0;
00678         bool m;
00679         for(; i < n; i++) {
00680             m = maskedAt(i);
00681             if((masked && m) || (!masked && !m)) {
00682                 xMin = xMax = xAt(i);
00683                 yMin = yMax = yAt(i);
00684                 break;
00685             }
00686         }
00687         if(i == n) return false;
00688         double temp;
00689         for(; i < n; i++) {
00690             m = maskedAt(i);
00691             if((masked && m) || (!masked && !m)) {
00692                 temp = xAt(i);
00693                 if(temp < xMin) xMin = temp;
00694                 if(temp > xMax) xMax = temp;
00695                 temp = yAt(i);
00696                 if(temp < yMin) yMin = temp;
00697                 if(temp > yMax) yMax = temp;
00698             }
00699         }
00700         return true;
00701     }
00702 };
00703 
00704 typedef PlotMaskedPointDataImpl<int> PlotMaskedPointIntData;
00705 typedef PlotMaskedPointDataImpl<unsigned int> PlotMaskedPointUIntData;
00706 typedef PlotMaskedPointDataImpl<float> PlotMaskedPointFloatData;
00707 typedef PlotMaskedPointDataImpl<double> PlotMaskedPointDoubleData;
00708 
00709 
00710 // Default implementation of PlotErrorData using standard containers, plus
00711 // scalars for the four errors.
00712 template <class T>
00713 class PlotScalarErrorDataImpl : public virtual PlotErrorData,
00714                                 public PlotPointDataImpl<T> {
00715 public:
00716     // Scalar error for top, bottom, left, and right.
00717     // <group>
00718     PlotScalarErrorDataImpl(vector<T>& x, vector<T>& y, T xLeftError,
00719             T xRightError, T yBottomError, T yTopError,
00720             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00721             m_xLeftError(xLeftError), m_xRightError(xRightError),
00722             m_yBottomError(yBottomError), m_yTopError(yTopError) { }
00723     PlotScalarErrorDataImpl(Vector<T>& x, Vector<T>& y, T xLeftError,
00724             T xRightError, T yBottomError, T yTopError,
00725             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00726             m_xLeftError(xLeftError), m_xRightError(xRightError),
00727             m_yBottomError(yBottomError), m_yTopError(yTopError) { }
00728     PlotScalarErrorDataImpl(T*& x, T*& y, unsigned int size, T xLeftError,
00729             T xRightError, T yBottomError, T yTopError,
00730             bool shouldDelete = false) :
00731             PlotPointDataImpl<T>(x, y, size, shouldDelete),
00732             m_xLeftError(xLeftError), m_xRightError(xRightError),
00733             m_yBottomError(yBottomError), m_yTopError(yTopError) { }
00734     // </group>
00735     
00736     // Single error for x and y.
00737     // <group>
00738     PlotScalarErrorDataImpl(vector<T>& x, vector<T>& y, T xError, T yError,
00739             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00740             m_xLeftError(xError), m_xRightError(xError),
00741             m_yBottomError(yError), m_yTopError(yError) { }
00742     PlotScalarErrorDataImpl(Vector<T>& x, Vector<T>& y, T xError, T yError,
00743             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00744             m_xLeftError(xError), m_xRightError(xError),
00745             m_yBottomError(yError), m_yTopError(yError) { }
00746     PlotScalarErrorDataImpl(T*& x, T*& y,unsigned int size, T xError, T yError,
00747             bool shouldDelete = false) :
00748             PlotPointDataImpl<T>(x, y, size, shouldDelete),
00749             m_xLeftError(xError), m_xRightError(xError),
00750             m_yBottomError(yError), m_yTopError(yError) { }
00751     // </group>
00752     
00753     // Single error for all values.
00754     // <group>
00755     PlotScalarErrorDataImpl(vector<T>& x, vector<T>& y, T error,
00756             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00757             m_xLeftError(error), m_xRightError(error), m_yBottomError(error),
00758             m_yTopError(error) { }
00759     PlotScalarErrorDataImpl(Vector<T>& x, Vector<T>& y, T error,
00760             bool shouldDelete=false): PlotPointDataImpl<T>(x, y, shouldDelete),
00761             m_xLeftError(error), m_xRightError(error), m_yBottomError(error),
00762             m_yTopError(error) { }
00763     PlotScalarErrorDataImpl(T*& x, T*& y, unsigned int size, T error,
00764             bool shouldDelete = false) :
00765             PlotPointDataImpl<T>(x, y, size, shouldDelete),
00766             m_xLeftError(error), m_xRightError(error), m_yBottomError(error),
00767             m_yTopError(error) { }
00768     // </group>
00769     
00770     // Destructor.
00771     ~PlotScalarErrorDataImpl() { }
00772     
00773     // Implements PlotErrorData getter methods.
00774     // <group>
00775     double xLeftErrorAt(unsigned int ) const { return m_xLeftError; }    
00776     double xRightErrorAt(unsigned int ) const { return m_xRightError; }
00777     double yBottomErrorAt(unsigned int ) const { return m_yBottomError; }
00778     double yTopErrorAt(unsigned int ) const { return m_yTopError; }
00779     // </group>
00780     
00781     // Implements PlotErrorData::errorMaxes().
00782     bool errorMaxes(double& xLeft, double& xRight, double& yBottom,
00783             double& yTop) {
00784         xLeft   = m_xLeftError;
00785         xRight  = m_xRightError;
00786         yBottom = m_yBottomError;
00787         yTop    = m_yTopError;
00788         return true;
00789     }
00790     
00791 private:
00792     T m_xLeftError, m_xRightError, m_yBottomError, m_yTopError;
00793 };
00794 
00795 typedef PlotScalarErrorDataImpl<int> PlotScalarErrorIntData;
00796 typedef PlotScalarErrorDataImpl<unsigned int> PlotScalarErrorUIntData;
00797 typedef PlotScalarErrorDataImpl<float> PlotScalarErrorFloatData;
00798 typedef PlotScalarErrorDataImpl<double> PlotScalarErrorDoubleData;
00799 
00800 
00801 // Default implementation of PlotErrorData using standard containers, plus
00802 // PlotPointDataImpls for the errors.
00803 template <class T>
00804 class PlotErrorDataImpl : public virtual PlotErrorData,
00805                           public PlotPointDataImpl<T> {
00806 public:
00807     // Symmetric error constructors.
00808     // <group>
00809     PlotErrorDataImpl(T*& x, T*& y, T*& xError, T*& yError, unsigned int size,
00810             bool shouldDelete = true) :
00811             PlotPointDataImpl<T>(x, y, size, shouldDelete),
00812             m_xError(xError, xError, size, shouldDelete),
00813             m_yError(yError, yError, size, shouldDelete) { }
00814     PlotErrorDataImpl(vector<T>& x, vector<T>& y, vector<T>& xError, 
00815             vector<T>& yError, bool shouldDelete = false) :
00816             PlotPointDataImpl<T>(x, y, shouldDelete),
00817             m_xError(xError, xError, shouldDelete),
00818             m_yError(yError, yError, shouldDelete) { }
00819     PlotErrorDataImpl(Vector<T>& x, Vector<T>& y, Vector<T>& xError,
00820             Vector<T>& yError, bool shouldDelete = false) :
00821             PlotPointDataImpl<T>(x, y, shouldDelete),
00822             m_xError(xError, xError, shouldDelete),
00823             m_yError(yError, yError, shouldDelete) { }
00824     // </group>
00825     
00826     // Asymmetric error constructors.
00827     // <group>
00828     PlotErrorDataImpl(T*& x, T*& y, T*& xLeftError, T*& xRightError,
00829             T*& yBottomError, T*& yTopError, unsigned int size,
00830             bool shouldDelete = true) :
00831             PlotPointDataImpl<T>(x, y, size, shouldDelete),
00832             m_xError(xLeftError, xRightError, size, shouldDelete),
00833             m_yError(yBottomError, yTopError, size, shouldDelete) { }
00834     PlotErrorDataImpl(vector<T>& x, vector<T>& y, vector<T>& xLeftError,
00835             vector<T>& xRightError, vector<T>& yBottomError,
00836             vector<T>& yTopError, bool shouldDelete = false) :
00837             PlotPointDataImpl<T>(x, y, shouldDelete),
00838             m_xError(xLeftError, xRightError, shouldDelete),
00839             m_yError(yBottomError, yTopError, shouldDelete) { }
00840     PlotErrorDataImpl(Vector<T>& x, Vector<T>& y, Vector<T>& xLeftError,
00841             Vector<T>& xRightError, Vector<T>& yBottomError,
00842             Vector<T>& yTopError, bool shouldDelete = false) :
00843             PlotPointDataImpl<T>(x, y, shouldDelete),
00844             m_xError(xLeftError, xRightError, shouldDelete),
00845             m_yError(yBottomError, yTopError, shouldDelete) { }
00846     // </group>
00847     
00848     ~PlotErrorDataImpl() { }
00849     
00850     // Overrides PlotPointDataImpl::willDeleteData().
00851     bool willDeleteData() const {
00852         return PlotPointDataImpl<T>::willDeleteData() &&
00853                m_xError.willDeleteData() && m_yError.willDeleteData();
00854     }
00855     
00856     // Overrides PlotPointDataImpl::setDeleteData().
00857     void setDeleteData(bool del = true) {
00858         m_xError.setDeleteData(del);
00859         m_yError.setDeleteData(del);
00860         PlotPointDataImpl<T>::setDeleteData(del);
00861     }
00862     
00863     // Implements PlotErrorData getter methods.
00864     // <group>
00865     double xLeftErrorAt(unsigned int i) const { return m_xError.xAt(i); }
00866     double xRightErrorAt(unsigned int i) const { return m_xError.yAt(i); }
00867     double yBottomErrorAt(unsigned int i) const { return m_yError.xAt(i); }
00868     double yTopErrorAt(unsigned int i) const { return m_yError.yAt(i); }
00869     // </group>
00870     
00871     // Implements PlotErrorData::errorMaxes().
00872     bool errorMaxes(double& xLeft, double& xRight, double& yBottom,
00873             double& yTop) {
00874         double temp;
00875         return m_xError.minsMaxes(temp, xLeft, temp, xRight) &&
00876                m_yError.minsMaxes(temp, yBottom, temp, yTop);
00877     }
00878     
00879 private:
00880     PlotPointDataImpl<T> m_xError, m_yError;
00881 };
00882 
00883 typedef PlotErrorDataImpl<int> PlotErrorIntData;
00884 typedef PlotErrorDataImpl<unsigned int> PlotErrorUIntData;
00885 typedef PlotErrorDataImpl<float> PlotErrorFloatData;
00886 typedef PlotErrorDataImpl<double> PlotErrorDoubleData;
00887 
00888 
00889 // Implementation of raster data using casa::Matrix.
00890 template <class T>
00891 class PlotRasterMatrixData : public virtual PlotRasterData {
00892 public:
00893     // Whether the indexing is (row,col) or (x,y).  Default is (row,col).
00894     enum Indexing {
00895         ROW_COL, X_Y
00896     };
00897     
00898     PlotRasterMatrixData(Matrix<T>& data, bool shouldDelete = false) :
00899             m_data(&data), m_origin(LLEFT), m_indexing(ROW_COL),
00900             m_shouldDelete(shouldDelete) {
00901         IPosition shape = data.shape();
00902         unsigned int n0 = shape[0] - 1, n1 = shape[1] - 1;
00903 
00904         m_0From = 0;
00905         m_0To = n0 + 1;
00906         m_1From = 0;
00907         m_1To = n1 + 1;
00908         m_0Pieces = (n0 + 1) / (m_0To - m_0From);
00909         m_1Pieces = (n1 + 1) / (m_1To - m_1From);
00910 
00911         double val = static_cast<double>(data(0, 0));
00912         m_valFrom = m_valTo = val;
00913         for(uInt i = 0; i < data.nrow(); i++) {
00914             for(uInt j = 0; j < data.ncolumn(); j++) {
00915                 val = static_cast<double>(data(i, j));
00916                 if(val < m_valFrom) m_valFrom = val;
00917                 if(val > m_valTo) m_valTo = val;
00918             }
00919         }
00920     }
00921     
00922     ~PlotRasterMatrixData() { if(m_shouldDelete) delete m_data; }
00923     
00924     // Implements PlotData::isValid().
00925     bool isValid() const { return true; }
00926     
00927     // Implements PlotData::willDeleteData().
00928     bool willDeleteData() const { return m_shouldDelete; }
00929     
00930     // Implements PlotData::setDeleteData().
00931     void setDeleteData(bool del = true) { m_shouldDelete = del; }
00932     
00933     // Implements PlotRasterData::origin().
00934     Origin origin() const { return m_origin; }
00935     
00936     // Implements PlotRasterData::setOrigin().
00937     void setOrigin(Origin o) {
00938         if(m_origin != o) {
00939             m_origin = o;
00940         }
00941     }
00942     
00943     // Implements PlotRasterData::xRange().
00944     prange_t xRange() const {
00945         if(m_indexing == X_Y) return prange_t(m_0From, m_0To);
00946         else return prange_t(m_1From, m_1To);
00947     }
00948     
00949     // Implements PlotRasterData::yRange().
00950     prange_t yRange() const {
00951         if(m_indexing == X_Y) return prange_t(m_1From, m_1To);
00952         else return prange_t(m_0From, m_0To);
00953     }
00954      
00955     // Implements PlotRasterData::setXRange().
00956     void setXRange(double from, double to) {
00957         if(from == to) return;
00958         if(from > to) {
00959             double temp = from;
00960             from = to;
00961             to = temp;
00962         }        
00963 
00964         if(m_indexing == X_Y) {
00965             m_0From = from;
00966             m_0To = to;
00967             m_0Pieces = (m_data->shape()[0]) / (m_0To - m_0From);
00968         } else {
00969             m_1From = from;
00970             m_1To = to;
00971             m_1Pieces = (m_data->shape()[1]) / (m_1To - m_1From);
00972         }
00973     }
00974         
00975     // Implements PlotRasterData::setYRange().
00976     void setYRange(double from, double to) {
00977         if(from == to) return;
00978         if(from > to) {
00979             double temp = from;
00980             from = to;
00981             to = temp;
00982         }
00983 
00984         if(m_indexing == X_Y) {
00985             m_1From = from;
00986             m_1To = to;
00987             m_1Pieces = (m_data->shape()[1]) / (m_1To - m_1From);
00988         } else {
00989             m_0From = from;
00990             m_0To = to;
00991             m_0Pieces = (m_data->shape()[0]) / (m_0To - m_0From);
00992         }
00993     }
00994     
00995     // Implements PlotRasterData::valueRange().
00996     prange_t valueRange() const { return prange_t(m_valFrom, m_valTo); }
00997     
00998     // Implements PlotRasterData::valueAt().
00999     double valueAt(double x, double y) const {
01000         if(m_indexing == X_Y) {
01001             if(x < m_0From || x > m_0To || y < m_1From || y > m_1To) return 0;
01002 
01003             int xi = (int)((x - m_0From) * m_0Pieces);
01004             int yi = (int)((y - m_1From) * m_1Pieces);
01005             if(xi >= m_data->shape()[0]) xi = m_data->shape()[0] - 1;
01006             if(yi >= m_data->shape()[1]) yi = m_data->shape()[1] - 1;
01007             
01008             return static_cast<double>((*m_data)(xi, yi));
01009 
01010         } else {
01011             if(x < m_1From || x > m_1To || y < m_0From || y > m_0To) return 0;
01012 
01013             int xi = (int)((x - m_1From) * m_1Pieces);
01014             int yi = (int)((y - m_0From) * m_0Pieces);
01015             if(xi >= m_data->shape()[1]) xi = m_data->shape()[1] - 1;
01016             if(yi >= m_data->shape()[0]) yi = m_data->shape()[0] - 1;
01017             
01018             return static_cast<double>((*m_data)(yi, xi));
01019         }
01020     }
01021     
01022     // Implements PlotRasterData::colorBarValues().
01023     vector<double>* colorBarValues(unsigned int max = 1000) const {
01024         vector<double>* v = new vector<double>();
01025 
01026         double val;
01027         bool found;
01028         for(unsigned int i = 0; i < m_data->nrow() && v->size() <= max; i++) {
01029             for(unsigned int j = 0; j < m_data->ncolumn() && v->size() <= max;
01030             j++) {
01031                 val = static_cast<double>((*m_data)(i, j));
01032                 found = false;
01033                 for(unsigned int k = 0; k < v->size() && !found; k++)
01034                     if(v->at(k) == val) found = true;
01035                 if(!found) v->push_back(val);
01036             }
01037         }
01038 
01039         return v;
01040     }
01041     
01042     // Gets/sets the indexing used for the matrix.
01043     // <group>
01044     Indexing indexing() const { return m_indexing; }    
01045     void setIndexing(Indexing i) { m_indexing = i; }
01046     // </group>
01047     
01048     // Gets/sets the matrix.
01049     // <group>
01050     Matrix<T>* matrix() { return m_data; }
01051     void setMatrix(Matrix<T>* m, bool shouldDelete = true) {
01052         if(m_shouldDelete) delete m_data;
01053         m_data = m;
01054         m_shouldDelete = shouldDelete;
01055     }
01056     // </group>
01057     
01058 private:
01059     Matrix<T>* m_data;
01060     double m_0From, m_0To;
01061     double m_1From, m_1To;
01062     double m_0Pieces, m_1Pieces;
01063     double m_valFrom, m_valTo;
01064     Origin m_origin;
01065     Indexing m_indexing;
01066     bool m_shouldDelete;
01067 };
01068 
01069 }
01070 
01071 #endif /*PLOTDATA_H_*/