00001 //# LatticeHistograms.h: generate histograms from a lattice 00002 //# Copyright (C) 1996,1997,1999,2000,2001 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 00028 #ifndef LATTICES_LATTICEHISTOGRAMS_H 00029 #define LATTICES_LATTICEHISTOGRAMS_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/lattices/LatticeMath/TiledCollapser.h> 00035 #include <casacore/lattices/LatticeMath/LatticeStatistics.h> 00036 #include <casacore/lattices/LatticeMath/LatticeProgress.h> 00037 #include <casacore/casa/Logging/LogIO.h> 00038 #include <casacore/casa/System/PGPlotter.h> 00039 #include <casacore/scimath/Mathematics/NumericTraits.h> 00040 #include <casacore/casa/iosfwd.h> 00041 00042 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00043 00044 //# Forward Declarations 00045 template <class T> class MaskedLattice; 00046 template <class T> class TempLattice; 00047 template <class T> class Vector; 00048 class IPosition; 00049 class PGPlotter; 00050 00051 // <summary> 00052 // Displays histograms of regions from a lattice. 00053 // </summary> 00054 00055 // <use visibility=export> 00056 00057 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00058 // </reviewed> 00059 00060 // <prerequisite> 00061 // <li> <linkto class=MaskedLattice>MaskedLattice</linkto> 00062 // </prerequisite> 00063 00064 // <etymology> 00065 // This is a class designed to display histograms from MaskedLattices 00066 // </etymology> 00067 00068 // <synopsis> 00069 // This class enable you to display and/or retrieve histograms evaluated over 00070 // specified regions from a MaskedLattice. The dimension of the region is arbitrary, but 00071 // the size of each dimension is always the size of the corresponding lattice axis. 00072 // The histograms are displayed as a function of location of the axes not 00073 // used to evaluate the histograms over. The axes which you evaluate the histograms 00074 // over are called the cursor axes, the others are called the display axes. 00075 // 00076 // For example, consider a lattice cube (call the axes xyz or [0,1,2]). You could 00077 // display histograms from xy planes (cursor axes [0,1]) as a function of z (display 00078 // axes [2]). Or you could retrieve histograms from the z axis (cursor axes [2]) 00079 // for each [x,y] location (display axes [0,1]). 00080 // 00081 // This class generates a "storage lattice" into which it writes the histograms. 00082 // It is from this storage lattice that the plotting and retrieval 00083 // arrays are drawn. The storage lattice is either in core or on disk 00084 // depending upon its size (if > 10% of memory given by .aipsrc system.resources.memory 00085 // then it goes into a disk-based PagedArray). If on disk, the 00086 // storage lattice is deleted when the <src>LatticeHistograms</src> 00087 // object destructs. 00088 // 00089 // 00090 // <note role=tip> 00091 // Note that for complex lattices, real and imaginary are treated independently. 00092 // They are binned and plotted separately. 00093 // </note> 00094 // 00095 // <note role=tip> 00096 // If you ignore return error statuses from the functions that set the 00097 // state of the class, the internal status of the class is set to bad. 00098 // This means it will just keep on returning error conditions until you 00099 // explicitly recover the situation. A message describing the last 00100 // error condition can be recovered with function errorMessage. 00101 00102 // </note> 00103 // </synopsis> 00104 00105 // <example> 00106 // <srcBlock> 00108 // 00109 // PagedImage<Float> inImage(inName); 00110 // 00112 // 00113 // LogOrigin or("myClass", "myFunction(...)", WHERE); 00114 // LogIO os(or); 00115 // ImageHistograms<Float> histo(inImage, os); 00116 // 00118 // 00119 // Vector<Int> cursorAxes(2) 00120 // cursorAxes(0) = 1; 00121 // cursorAxes(1) = 2; 00122 // if (!histo.setAxes(cursorAxes)) return 1; 00123 // 00125 // 00126 // if (!histo.setList(True)) return 1; 00127 // String device = "/xs"; 00128 // Vector<Int> nxy(2); 00129 // nxy(0) = 3; 00130 // nxy(1) = 3; 00131 // if (!histo.setPlotting(device, nxy)) return 1; 00132 // 00134 // 00135 // if (!histo.display ()) return 1; 00136 // 00138 // 00139 // Array<Float> values, counts; 00140 // if (!histo.getHistograms(values, counts)) return 1; 00141 // 00142 // </srcBlock> 00143 // In this example, a <src>PagedImage</src> is constructed. We set the cursor axes 00144 // to be the y and z axes so we make a histogram of each yz plane as a function 00145 // of x location on the PGPLOT device "/xs" with 9 subplots per page. 00146 // After the plotting we also retrieve the histograms into an array. 00147 // </example> 00148 00149 // <motivation> 00150 // The generation of histograms from an image is a basic and necessary capability. 00151 // </motivation> 00152 // 00153 // <todo asof="2000/04/04"> 00154 // <li> Make ascii listing of histograms as well as plots if desired 00155 // </todo> 00156 // 00157 00158 00159 template <class T> class LatticeHistograms 00160 { 00161 public: 00162 00163 // Constructor takes the MaskedLattice and a <src>LogIO</src> object for logging. 00164 // You can also specify whether you want to see progress meters or not. 00165 // You can force the storage lattice to be disk based, otherwise 00166 // the decision for core or disk is taken for you. 00167 LatticeHistograms(const MaskedLattice<T>& lattice, 00168 LogIO& os, 00169 Bool showProgress=True, 00170 Bool forceDisk=False); 00171 00172 // Constructor takes the MaskedLattice only. In the absence of a logger you get no messages. 00173 // This includes error messages and potential listing of statistics. 00174 // You can specify whether you want to see progress meters or not. 00175 // You can force the storage lattice to be disk based, otherwise 00176 // the decision for core or disk is taken for you. 00177 LatticeHistograms(const MaskedLattice<T>& lattice, 00178 Bool showProgress=True, 00179 Bool forceDisk=False); 00180 00181 // Copy constructor (copy semantics) 00182 LatticeHistograms(const LatticeHistograms<T> &other); 00183 00184 // Destructor 00185 virtual ~LatticeHistograms (); 00186 00187 // Assignment operator (copy semantics) 00188 LatticeHistograms<T> &operator=(const LatticeHistograms<T> &other); 00189 00190 // Set the cursor axes (0 relative). A return value of <src>False</src> 00191 // indicates you have asked for an invalid axis or that the internal 00192 // status of the class is bad. The default state of the class is to set 00193 // the cursor axes to all axes in the lattice. 00194 Bool setAxes (const Vector<Int>& cursorAxes); 00195 00196 // Set the number of bins for the histogram. Note that the bin width is 00197 // worked out for each histogram separately from the data minimum and maximum. 00198 // The default state of the class is to set 25 bins. A return value of <src>False</src> 00199 // indicates you gave a non-positive bin width or that the internal status of the 00200 // class is bad. 00201 Bool setNBins (const uInt& nBins); 00202 00203 // Specify a pixel intensity range for which all pixels in that range are 00204 // included. A vector of length 1 for <src>include</src> means that the 00205 // range will be set to <src>-abs(include(0))</src> to <src>abs(include(0))</src>. 00206 // A return value of <src>False</src> indicates that the internal 00207 // status of the class is bad. If you don't call this function, the default 00208 // state of the class is to include all pixels. 00209 Bool setIncludeRange (const Vector<T>& include); 00210 00211 // Specify that a Gaussian overlay should be plotted on the histogram. This 00212 // Gaussian has the same mean and standard deviation as the data that were 00213 // binned, and the same integral as the histogram. A return value of <src>False</src> 00214 // indicates that the internal status of the class is bad. The default state of 00215 // the class is to not draw a Gaussian overlay. 00216 Bool setGaussian (const Bool& doGauss); 00217 00218 // Specify the form of the histogram. It can be plotted linearly or 00219 // logarithmically, and cumulatively or non-cumulatively. A return value 00220 // of <src>False</src> indicates that the internal status of the class is bad. 00221 // The default state of the class is to draw the histograms linearly and 00222 // non-cumulatively. 00223 Bool setForm (const Bool& doLog, const Bool& doCumu); 00224 00225 // This function allows you to control whether some statistics of the 00226 // data that contributed to the histogram are written to the output 00227 // stream. A return value of <src>False</src> indicates that the internal 00228 // status of the class is bad. The default state of the class is to not 00229 // list statistics. 00230 Bool setStatsList(const Bool& doList); 00231 00232 // This function sets the name of the PGPLOT plotting device and the number of 00233 // subplots in x and y per page. If you set <src>plotter</src> but offer 00234 // a zero length array for <src>nxy</src> then <src>nxy</src> is set 00235 // to [1,1]. A return value of <src>False</src> indicates invalid 00236 // plotting arguments or that the internal status of the class is bad. If you 00237 // don't call this function, the default state of the class is to not set 00238 // a plotting device. 00239 Bool setPlotting(PGPlotter& plotter, 00240 const Vector<Int>& nxy); 00241 00242 // Display the histograms by plotting them. A return value of <src>False</src> 00243 // indicates an invalid plotting device, or that the internal status of the class is bad. 00244 // If you don't call this function you won't see any histograms. 00245 Bool display (); 00246 00247 // CLose the plotter 00248 void closePlotting(); 00249 00250 // Return the display axes 00251 Vector<Int> displayAxes() const {return displayAxes_p;} 00252 00253 // This function retrieves the histograms into <src>Array</src>. The shape of the first 00254 // dimension of this array is the number of bins. The rest of the shape of the 00255 // array is the shape of the display axes (e.g. if the shape of the lattice is 00256 // [nx,ny,nz] and you ask for histograms of the y axis the shape of the returned 00257 // array would be [nbins,nx,nz]. The histograms are retrieved in the form 00258 // specified by the <src>setForm</src> function. The arrays are resized internally. 00259 // A return value of <src>False</src> indicates that the internal status of the class is bad. 00260 Bool getHistograms (Array<T>& values, Array<T>& counts); 00261 00262 // in this version, the set of stats for each histogram is also returned. The 00263 // stats array has the shape of the display axes. 00264 Bool getHistograms (Array<T>& values, Array<T>& counts, Array<Vector<T> >& stats); 00265 00266 00267 // This function retrieves the histogram at the specified location 00268 // into <src>Vectors</src>. The histogram is retrieved in the form 00269 // specified by the <src>setForm</src> function. The vectors are resized 00270 // internally. If <src>posInLattice=True</src> then the location is a 00271 // location in the input lattice. Any positions on the display axes 00272 // are ignored. Otherwise, you should just give locations for 00273 // the display axes only. A return value of <src>False</src> indicates that 00274 // the internal status of the class is bad. 00275 Bool getHistogram (Vector<T>& values, 00276 Vector<T>& counts, 00277 const IPosition& pos, 00278 const Bool posInLattice=False); 00279 00280 // Reset argument error condition. If you specify invalid arguments to 00281 // one of the above <src>set</src> functions, an internal flag will be set which will 00282 // prevent the work functions from doing anything (should you have chosen 00283 // to ignore the Boolean return values of the <src>set</src> functions). 00284 // This function allows you to reset that internal state to good. 00285 void resetError () {goodParameterStatus_p = True;}; 00286 00287 // Recover last error message 00288 String errorMessage() const {return error_p;}; 00289 00290 // Set a MaskedLattice. A return value of <src>False</src> indicates the 00291 // lattice had an invalid type or that the internal status of the class is bad. 00292 Bool setNewLattice (const MaskedLattice<T>& lattice); 00293 00294 // These things are protected only so that they are available to ImageHistograms 00295 // which inherits from LatticeHistograms 00296 00297 protected: 00298 LogIO os_p; 00299 Bool goodParameterStatus_p; 00300 Vector<Int> cursorAxes_p, displayAxes_p; 00301 String error_p; 00302 00303 // Given a location in the histogram storage lattice, convert those locations on the 00304 // non-histogram axis (the first one) relative to the parent or current lattice 00305 IPosition locHistInLattice (const IPosition& histPosition, 00306 Bool relativeToParent=True) const; 00307 00308 private: 00309 00310 // A useful typedef 00311 typedef typename NumericTraits<T>::PrecisionType AccumType; 00312 00313 const MaskedLattice<T>* pInLattice_p; 00314 TempLattice<T>* pStoreLattice_p; 00315 LatticeStatistics<T>* pStats_p; 00316 Bool binAll_p, needStorageLattice_p; 00317 Bool doCumu_p, doGauss_p, doList_p, doLog_p; 00318 Bool haveLogger_p, showProgress_p, forceDisk_p; 00319 uInt nBins_p; 00320 PGPlotter plotter_p; 00321 Vector<Int> nxy_p; 00322 Vector<T> range_p; 00323 IPosition blcParent_p; 00324 00325 00326 // Convert a <tt>T</tt> to a <tt>Float</tt> for plotting 00327 static Float convertT (const T value) {return Float(std::real(value));}; 00328 00329 // Convert a <tt>Float</tt> (from plotting) to a <tt>T</tt> 00330 static T convertF (const Float value) {return T(value);}; 00331 00332 // Display histograms as a function of display axis 00333 Bool displayHistograms (); 00334 00335 // Display one histogram 00336 Bool displayOneHistogram (const T&linearSum, 00337 const T&linearYMax, 00338 const IPosition& histPos, 00339 const Vector<T> &stats, 00340 const Vector<T>& values, 00341 const Vector<T>& counts, 00342 PGPlotter& plotter); 00343 00344 00345 // Fish out and convert to the appropriate form one histogram from the 00346 // storage lattice 00347 void extractOneHistogram (T& linearSum, 00348 T& linearYMax, 00349 Vector<T>& values, 00350 Vector<T>& counts, 00351 const Vector<T>& stats, 00352 const Vector<T>& intCounts); 00353 00354 // Iterate through the lattice and generate the histogram accumulation lattice 00355 Bool generateStorageLattice(); 00356 00357 // Get the statistics from the statistics object for the current 00358 // location of either the input lattice, or the histogram storage lattice 00359 void getStatistics (Vector<T> &stats, 00360 const IPosition &pos) const; 00361 00362 // List statistics 00363 void listStatistics(LogIO& os, const Vector<T>& stats, T binWidth); 00364 00365 00366 // Fill histograms storage lattice 00367 void makeHistograms(); 00368 00369 // Create and fill statistics object 00370 Bool makeStatistics(); 00371 00372 // Check/set include pixel range 00373 Bool setInclude (Vector<T>& range, 00374 Bool& noInclude, 00375 const Vector<T>& include, 00376 ostream& os); 00377 00378 // Set stream attributes 00379 void setStream (ostream& os, Int oPrec); 00380 00381 // Make a string with pixel coordinates of display axes. This function 00382 // is over-ridden by ImageHistograms which inherits from LatticeHistograms. 00383 virtual String writeCoordinates(const IPosition& histPos) const; 00384 00385 // Write values of display axes on plots 00386 Bool writeDispAxesValues (const String& coords, 00387 PGPlotter& plotter, 00388 Float nchar) const; 00389 }; 00390 00391 00392 00393 // <summary> Generate histograms, tile by tile, from a masked lattice </summary> 00394 // 00395 // <use visibility=export> 00396 // 00397 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00398 // </reviewed> 00399 // 00400 // <prerequisite> 00401 // <li> <linkto class=LatticeApply>LatticeApply</linkto> 00402 // <li> <linkto class=TiledCollapser>TiledCollapser</linkto> 00403 // </prerequisite> 00404 // 00405 // <etymology> 00406 // This class is used by <src>LatticeHistograms</src> to generate 00407 // histograms from an input <src>MaskedLattice</src>. 00408 // The input lattice is iterated through in tile-sized chunks 00409 // and fed to an object of this class. 00410 // </etymology> 00411 // 00412 // <synopsis> 00413 // <src>HistTiledCollapser</src> is derived from <src>TiledCollapser</src> which 00414 // is a base class used to define methods. Objects of this base class are 00415 // used by <src>LatticeApply</src> functions. In this particular case, 00416 // we are interested in <src>LatticeApply::tiledApply</src>. This function iterates 00417 // through a <src>MaskedLattice</src> and allows you to collapse one or more 00418 // axes, computing some values from it, and placing those values into 00419 // an output <src>MaskedLattice</src>. It iterates through the input 00420 // lattice in optimal tile-sized chunks. <src>LatticeHistograms</src> 00421 // uses a <src>HistTiledCollapser</src> object which it gives to 00422 // <src>LatticeApply::tiledApply</src> for digestion. After it has 00423 // done its work, <src>LatticeHistograms</src> then accesses the output 00424 // <src>Lattice</src> that it made. 00425 // </synopsis> 00426 // 00427 // <example> 00428 // <srcblock> 00430 // 00431 // HistTiledCollapser<T> collapser(pStats, nBins_p); 00432 // 00435 // 00436 // Int newOutAxis = 0; 00437 // 00440 // 00441 // LatticeApply<T>::tiledApply(outLattice, inLattice, 00442 // collapser, collapseAxes, 00443 // newOutAxis); 00444 // 00445 // </srcblock> 00446 // In this example, a collapser is made and passed to LatticeApply. 00447 // Afterwards, the output Lattice is available for use. 00448 // The Lattices must all be the correct shapes on input to tiledApply 00449 // </example> 00450 // 00451 // <motivation> 00452 // The LatticeApply classes enable the ugly details of optimal 00453 // Lattice iteration to be hidden from the user. 00454 // </motivation> 00455 // 00456 // <todo asof="1998/05/10"> 00457 // <li> 00458 // </todo> 00459 00460 template <class T> 00461 class HistTiledCollapser : public TiledCollapser<T,T> 00462 { 00463 00464 public: 00465 // Constructor 00466 HistTiledCollapser(LatticeStatistics<T>* pStats, uInt nBins); 00467 00468 virtual ~HistTiledCollapser(); 00469 00470 // Initialize process, making some checks 00471 virtual void init (uInt nOutPixelsPerCollapse); 00472 00473 // Initialize the accumulator 00474 virtual void initAccumulator (uInt n1, uInt n3); 00475 00476 // Process the data in the current chunk. 00477 virtual void process ( 00478 uInt accumIndex1, 00479 uInt accumIndex3, 00480 const T* inData, 00481 const Bool* inMask, 00482 uInt inDataIncr, 00483 uInt inMaskIncr, 00484 uInt nrval, 00485 const IPosition& startPos, 00486 const IPosition& shape 00487 ); 00488 00489 // End the accumulation process and return the result arrays 00490 virtual void endAccumulator(Array<T>& result, 00491 Array<Bool>& resultMask, 00492 const IPosition& shape); 00493 00494 // Can handle null mask 00495 virtual Bool canHandleNullMask() const {return True;}; 00496 00497 private: 00498 LatticeStatistics<T>* pStats_p; 00499 Block<T>* pHist_p; 00500 uInt nBins_p; 00501 uInt n1_p; 00502 uInt n3_p; 00503 }; 00504 00505 00506 00507 } //# NAMESPACE CASACORE - END 00508 00509 #ifndef CASACORE_NO_AUTO_TEMPLATES 00510 #include <casacore/lattices/LatticeMath/LatticeHistograms.tcc> 00511 #endif //# CASACORE_NO_AUTO_TEMPLATES 00512 #endif