casa
$Rev:20696$
|
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_*/