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

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1