LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis/test - dImageHistograms.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 98 164 59.8 %
Date: 2023-11-02 14:27:30 Functions: 1 1 100.0 %

          Line data    Source code
       1             : //# dImageHistograms.cc: This program generates histograms from images
       2             : //#
       3             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2003
       4             : //# Associated Universities, Inc. Washington DC, USA.
       5             : //#
       6             : //# This library is free software; you can redistribute it and/or modify it
       7             : //# under the terms of the GNU Library General Public License as published by
       8             : //# the Free Software Foundation; either version 2 of the License, or (at your
       9             : //# option) any later version.
      10             : //#
      11             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      12             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      14             : //# License for more details.
      15             : //#
      16             : //# You should have received a copy of the GNU Library General Public License
      17             : //# along with this library; if not, write to the Free Software Foundation,
      18             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      19             : //#
      20             : //# Correspondence concerning AIPS++ should be addressed as follows:
      21             : //#        Internet email: aips2-request@nrao.edu.
      22             : //#        Postal address: AIPS++ Project Office
      23             : //#                        National Radio Astronomy Observatory
      24             : //#                        520 Edgemont Road
      25             : //#                        Charlottesville, VA 22903-2475 USA
      26             : //#
      27             : //# $Id: dImageHistograms.cc 20567 2009-04-09 23:12:39Z gervandiepen $
      28             : //
      29             : // IMHIST iterates through an image and creates and displays histograms from
      30             : //    data chunks specified by the axes keyword. 
      31             : //
      32             : //
      33             : //   in       The name on the input aips++ image.  Currently must be of type <Float>
      34             : //            and can be of any dimension.
      35             : //
      36             : //            There is no default.
      37             : //
      38             : //   axes     An array of integers (1 relative) specifying which axes are to be 
      39             : //            histogrammed and which ones the histograms will be displayed as 
      40             : //            a function of.  For example,  axes=3  would cause imhist to work
      41             : //            out histograms of the third (z) axis and display them as a function of
      42             : //              location along the first (x) and second (y) axes.   axes=1,3 would cause
      43             : //            histograms of 1-3 (x-z) planes to be made and then to be displayed as
      44             : //            a function of the second axis (y) location.  
      45             : // 
      46             : //            The default is to make a histogram of the entire image.
      47             : //    
      48             : // 
      49             : //   blc,trc  Region (1 relative)
      50             : //   inc      Increment to step through image
      51             : //
      52             : //   nbins    This specifies the number of bins, which is the same for each 
      53             : //            histogram.  Note that the bin width is worked out for each histogram 
      54             : //            separately from the data minimum and maximum for that data chunk
      55             : //            (unless you set the range keyword).
      56             : //          
      57             : //            The default is 25
      58             : //         
      59             : //   include  This specifies a range of pixel values to *include* in generating
      60             : //            the histograms.  If two values are given then include pixels in
      61             : //            the range include(1) to include(2).  If one value is given, then
      62             : //            include pixels in the range -abs(include) to abs(include)
      63             : //            This range applies to all histograms.
      64             : //             
      65             : //            The default is to include all data.
      66             : //
      67             : //   gauss    If true, a Gaussian overlay with the same mean, sigma
      68             : //            (of the pixels that were binned) and integral (of the histogram)
      69             : //            will be drawn on each histogram.
      70             : //
      71             : //            The default is true.
      72             : //
      73             : //   cumu     If true, a cumulative histogram is drawn.
      74             : //
      75             : //            The defaults is false.
      76             : //
      77             : //   log      If true, the log of the histogram values is drawn.
      78             : //
      79             : //            The default is false.
      80             : //
      81             : //   list     If true list some statistical information about each histogram
      82             : //
      83             : //            The default is false.
      84             : //
      85             : //   plotter  The PGPLOT device.
      86             : //
      87             : //            The default is /xs
      88             : //
      89             : //   nxy      The number of subplots to put on each page in x and y.  Each 
      90             : //            histogram takes one subplot.
      91             : //
      92             : //            The default is 1,1
      93             : //
      94             : // To do:
      95             : //   add keyword exclude ?  Bit hard as requires restucturing of min/max
      96             : //   storage image
      97             : //
      98             : #include <casacore/casa/aips.h>
      99             : #include <casacore/casa/Arrays.h>
     100             : #include <casacore/casa/Exceptions/Error.h>
     101             : #include <casacore/casa/Inputs/Input.h>
     102             : #include <casacore/casa/Logging.h>
     103             : #include <casacore/casa/BasicSL/String.h>
     104             : 
     105             : #include <casacore/images/Images/PagedImage.h>
     106             : #include <casacore/images/Images/SubImage.h>
     107             : #include <casacore/images/Regions/ImageRegion.h>
     108             : #include <imageanalysis/ImageAnalysis/ImageHistograms.h>
     109             : #include <casacore/lattices/LRegions/LCSlicer.h>
     110             : #include <casacore/lattices/LRegions/LCBox.h>
     111             : #include <casacore/casa/System/PGPlotter.h>
     112             : #include <casacore/casa/OS/EnvVar.h>
     113             : 
     114             : #include <casacore/casa/iostream.h>
     115             : 
     116             : 
     117             : #include <casacore/casa/namespace.h>
     118             : enum defaults {AXES, REGION, RANGE, NDEFAULTS};
     119             : 
     120             : 
     121           1 : int main (int argc, const char* argv[])
     122             : {
     123             : try {
     124             : 
     125           1 :    Input inputs(1);
     126           1 :    inputs.version ("$Revision: 20567 $");
     127             : 
     128             : 
     129             : // Get inputs
     130           1 :     String casadata = EnvironmentVariable::get("CASADATA");
     131           1 :     if (casadata.empty()) {
     132           0 :         cerr << "CASADATA env variable not defined. Can't find fixtures. Did you source the casainit.(c)sh file?" << endl;
     133           0 :         return 1;
     134             :     }
     135           3 :     String *parts = new String[2];
     136           1 :     split(casadata, parts, 2, String(" "));
     137           1 :     String datadir = parts[0] + "/unittest/image/";
     138           4 :     delete [] parts;
     139             : 
     140           1 :    String name = datadir + "test_image.im";
     141           1 :    inputs.create("in", name, "Input image name");
     142           1 :    inputs.create("axes", "-10", "Cursor axes");
     143           1 :    inputs.create("blc", "-10", "blc");
     144           1 :    inputs.create("trc", "-10", "trc");
     145           1 :    inputs.create("inc", "-10", "inc");
     146           1 :    inputs.create("nbins", "25", "Number of bins");
     147           1 :    inputs.create("include", "0.0", "Pixel range to include");
     148           1 :    inputs.create("gauss", "true", "Plot Gaussian equivalent ?");
     149           1 :    inputs.create("cumu", "false", "Plot cumulative histogram ?");
     150           1 :    inputs.create("log", "false", "Take log of y axis ?");
     151           1 :    inputs.create("list", "false", "List statistics for each histogram");
     152           1 :    inputs.create("plotter", "", "Plot device");
     153           1 :    inputs.create("nxy", "1,1", "Number of subplots in x & y");
     154           1 :    inputs.create("disk", "false", "Force storage image to be disk based");
     155           1 :    inputs.readArguments(argc, argv);
     156             : 
     157           1 :    const String in = inputs.getString("in");
     158           1 :    const Block<Int> cursorAxesB(inputs.getIntArray("axes"));
     159           1 :    const Block<Int> blcB(inputs.getIntArray("blc"));
     160           1 :    const Block<Int> trcB(inputs.getIntArray("trc"));
     161           1 :    const Block<Int> incB(inputs.getIntArray("inc"));
     162           1 :    const Int nBins = inputs.getInt("nbins");
     163           1 :    const Bool doGauss = inputs.getBool("gauss");
     164           1 :    const Bool doCumu = inputs.getBool("cumu");
     165           1 :    const Bool doLog = inputs.getBool("log");
     166           1 :    const Block<Double> includeB = inputs.getDoubleArray("include");
     167           1 :    const Bool doList = inputs.getBool("list");
     168           1 :    const Block<Int> nxyB(inputs.getIntArray("nxy"));
     169           1 :    const String device = inputs.getString("plotter");
     170           1 :    const Bool force = inputs.getBool("disk");
     171             : 
     172             : 
     173             : // Create defaults array
     174             :  
     175           1 :    Vector<Bool> validInputs(NDEFAULTS);
     176           1 :    validInputs = false;
     177           2 :    LogOrigin lor("imhist", "main()", WHERE);
     178           1 :    LogIO os(lor);
     179             : 
     180             : // Check inputs
     181             : 
     182           1 :    if (in.empty()) {
     183           0 :      os << LogIO::SEVERE << "You must give an input image" << LogIO::POST;
     184           0 :      return 1;
     185             :    }
     186             : 
     187             : // Convert cursor axes array to a vector (0 relative)
     188             :   
     189           1 :    Vector<Int> cursorAxes;
     190           1 :    if (cursorAxesB.nelements() == 1 && cursorAxesB[0] == -10) {
     191           1 :       cursorAxes.resize(0);   
     192             :    } else {
     193           0 :       cursorAxes.resize(cursorAxesB.nelements());
     194           0 :       for (uInt i=0; i<cursorAxes.nelements(); i++) cursorAxes(i) = cursorAxesB[i] - 1;
     195           0 :       validInputs(AXES) = true;
     196             :    }
     197             : 
     198             : // Convert region things to IPositions (0 relative)
     199             :    
     200           1 :    IPosition blc;
     201           1 :    IPosition trc;
     202           1 :    IPosition inc;
     203           1 :    if (blcB.nelements() == 1 && blcB[0] == -10) {
     204           1 :       blc.resize(0);
     205             :    } else {
     206           0 :       blc.resize(blcB.nelements());
     207           0 :       for (uInt i=0; i<blcB.nelements(); i++) blc(i) = blcB[i] - 1;
     208           0 :       validInputs(REGION) = true;
     209             :    }
     210           1 :    if (trcB.nelements() == 1 && trcB[0] == -10) {
     211           1 :       trc.resize(0);
     212             :    } else {
     213           0 :       trc.resize(trcB.nelements());
     214           0 :       for (uInt i=0; i<trcB.nelements(); i++) trc(i) = trcB[i] - 1;
     215           0 :       validInputs(REGION) = true;
     216             :    }
     217           1 :    if (incB.nelements() == 1 && incB[0] == -10) {
     218           1 :       inc.resize(0);
     219             :    } else {
     220           0 :       inc.resize(incB.nelements());
     221           0 :       for (uInt i=0; i<incB.nelements(); i++) inc(i) = incB[i];
     222           0 :       validInputs(REGION) = true;
     223             :    }
     224             : 
     225             : // Convert inclusion range to vector
     226             :    
     227           1 :    Vector<Float> include(includeB.nelements());
     228             :    uInt i;
     229           2 :    for (i=0;i<include.nelements(); i++) {
     230           1 :      include(i) = includeB[i]; 
     231             :    }
     232           1 :    if (include.nelements() == 1 && include(0)==0) {
     233           1 :       include.resize(0);
     234             :    } else {
     235           0 :       validInputs(RANGE) = true;
     236             :    }
     237             : 
     238             : 
     239             : // Plotting things
     240             :  
     241           1 :    Vector<Int> nxy;
     242           1 :    if (nxyB.nelements() == 1 && nxyB[0] == -1) {
     243           0 :       nxy.resize(0);
     244             :    } else {
     245           1 :       nxy.resize(nxyB.nelements());
     246           3 :       for (i=0;i<nxy.nelements(); i++) nxy(i) = nxyB[i];
     247             :    }
     248             : 
     249             : 
     250             : // Do the work 
     251             :     
     252           1 :    os << LogIO::NORMAL << "Using image " << in << LogIO::POST;
     253           1 :    DataType imageType = imagePixelType(in);
     254           1 :    if (imageType==TpFloat) {
     255             :    
     256             : // Construct image
     257             :      
     258           1 :       PagedImage<Float> inImage(in);
     259           1 :       SubImage<Float>* pSubImage2 = 0;
     260             :     
     261           1 :       if (validInputs(REGION)) {  
     262           0 :          LCBox::verify(blc, trc, inc, inImage.shape());
     263           0 :          cout << "Selected region : " << blc+1<< " to "  
     264           0 :               << trc+1 << endl;
     265           0 :          const LCSlicer region(blc, trc);
     266             : //
     267           0 :          SubImage<Float>* pSubImage = 0;
     268           0 :          if (inImage.isMasked()) {
     269             :             ImageRegion mask =
     270           0 :               inImage.getRegion(inImage.getDefaultMask(),
     271           0 :                                 RegionHandler::Masks);
     272           0 :             pSubImage = new SubImage<Float>(inImage, mask);
     273             :          } else {
     274           0 :             pSubImage = new SubImage<Float>(inImage);
     275             :          }
     276           0 :          pSubImage2 = new SubImage<Float>(*pSubImage, ImageRegion(region));
     277           0 :          delete pSubImage;
     278             :       } else {
     279           1 :          if (inImage.isMasked()) {
     280             :             ImageRegion mask =
     281           0 :               inImage.getRegion(inImage.getDefaultMask(),
     282           0 :                                 RegionHandler::Masks);
     283           0 :             pSubImage2 = new SubImage<Float>(inImage, mask);
     284             :          } else {
     285           1 :             pSubImage2 = new SubImage<Float>(inImage);
     286             :          }
     287             :       }
     288             : 
     289             : // Construct histogram object
     290             :   
     291           1 :       casa::ImageHistograms<Float> histo(*pSubImage2, os, true, force);
     292           1 :       if (pSubImage2!=0) delete pSubImage2;
     293             : 
     294             :    
     295             : // Set state
     296             :       
     297           1 :       if (validInputs(AXES)) {
     298           0 :          if (!histo.setAxes(cursorAxes)) {
     299           0 :             os << histo.errorMessage() << LogIO::POST;
     300           0 :             return 1;
     301             :          }
     302             :       }
     303           1 :       if (!histo.setNBins(nBins)) {
     304           0 :          os << histo.errorMessage() << LogIO::POST;
     305           0 :          return 1;
     306             :       }
     307           1 :       if (validInputs(RANGE)) {
     308           0 :          if (!histo.setIncludeRange(include)) {
     309           0 :             os << histo.errorMessage() << LogIO::POST;
     310           0 :             return 1;
     311             :          }
     312             :       }
     313           1 :       if (!histo.setGaussian (doGauss)) {
     314           0 :          os << histo.errorMessage() << LogIO::POST;
     315           0 :          return 1;
     316             :       }
     317           1 :       if (!histo.setForm(doLog, doCumu)) {
     318           0 :          os << histo.errorMessage() << LogIO::POST;
     319           0 :          return 1;
     320             :       }
     321           1 :       if (!histo.setStatsList(doList)) {
     322           0 :          os << histo.errorMessage() << LogIO::POST;
     323           0 :          return 1;
     324             :       }
     325           1 :       if (!device.empty()) {
     326           0 :          PGPlotter plotter(device);
     327           0 :          if (!histo.setPlotting(plotter, nxy)) {
     328           0 :             os << histo.errorMessage() << LogIO::POST;
     329           0 :             return 1;
     330             :          }
     331             :       }
     332             : 
     333             : // Display histograms
     334             : 
     335           1 :       if (!histo.display()) {
     336           0 :          os << histo.errorMessage() << LogIO::POST;
     337           0 :          return 1;
     338             :       }
     339             : 
     340             : // Get histograms   
     341             : 
     342           1 :       Array<Float> values, counts;
     343           1 :       os << LogIO::NORMAL << "Recovering histogram arrays" << LogIO::POST;
     344           1 :       if (!histo.getHistograms(values,counts)) {
     345           0 :          os << histo.errorMessage() << LogIO::POST;
     346           0 :          return 1;
     347             :       }
     348             : //      cout << "values=" << values << endl;
     349             : //      cout << "counts=" << counts << endl;
     350             :  
     351           1 :       os << LogIO::NORMAL << "Recovering individual histogram arrays" << LogIO::POST;
     352           1 :       Vector<Float> valuesV, countsV;
     353           1 :       IPosition pos(histo.displayAxes().nelements(),0);
     354           1 :       if (!histo.getHistogram(valuesV,countsV,pos,false)) {
     355           0 :          os << histo.errorMessage() << LogIO::POST;
     356           0 :          return 1;
     357             :       }
     358             : 
     359             : //      cout << "values=" << valuesV << endl;
     360             : //      cout << "counts=" << countsV << endl;
     361             : 
     362             : 
     363             : // Test copy constructor
     364             : 
     365           1 :       os << LogIO::NORMAL << "Applying copy constructor" << endl;
     366           1 :       casa::ImageHistograms<Float> histo2(histo);
     367             : 
     368             : // Test assignment operator
     369             : 
     370           1 :       os << "Applying assignment operator" << LogIO::POST;
     371           1 :       histo = histo2;
     372             : 
     373             : // Test setNewImage
     374             :  
     375           1 :      os << "Test setNewImage" << LogIO::POST;
     376           1 :      if (!histo.setNewImage(inImage)) {
     377           0 :          os << histo.errorMessage() << LogIO::POST;
     378           0 :          return 1;
     379             :      } 
     380           1 :      if (!histo.display()) {
     381           0 :          os << histo.errorMessage() << LogIO::POST;
     382           0 :          return 1;
     383             :      }
     384             : 
     385             :    } else {
     386             :       os << "images of type " << Int(imageType)
     387           0 :          << " not yet supported" << endl;
     388           0 :       return 1;
     389             :    }
     390             : }
     391           0 :    catch (AipsError x) {
     392           0 :       cerr << "aipserror: error " << x.getMesg() << endl;
     393           0 :       return 1;
     394             :   }
     395             : 
     396           1 :  return 0;
     397             : 
     398             : }

Generated by: LCOV version 1.16