//# Copyright (C) 1996,1997,1998,1999,2000,2001,2002 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# #ifndef IMAGEANALYSIS_IMAGEPOLTASK_H #define IMAGEANALYSIS_IMAGEPOLTASK_H #include <imageanalysis/ImageAnalysis/ImageTask.h> namespace casa { // <summary> // Begin moving polarization tasks to ImageTask framework. // </summary> // <use visibility=export> // <prerequisite> // <li> <linkto class=casacore::ImageExpr>ImageExpr</linkto> // <li> <linkto class=casacore::ImageInterface>ImageInterface</linkto> // </prerequisite> // <etymology> // Polarimetric analysis of Images // </etymology> // <synopsis> // This class provides polarimetric image analysis capability. // It takes an image with a casacore::Stokes axis (some combination // of IQUV is needed) as its input. // // Many functions return casacore::ImageExpr objects. These are // read-only images. // // Sometimes the standard deviation of the noise is needed. // This is for debiasing polarized intensity images or working out // error images. By default it is worked out for you with a // clipped mean algorithm. However, you can provide sigma if you // know it accurately. It should be the standard deviation of the noise in // the absence of signal. You won't measure that very well from // casacore::Stokes I if it is dynamic range limited. Better to get it from // V or Q or U. When this class needs the standard deviation of // the noise, it will try and get it from V or Q and U and finally I. // // However, note that the functions sigmaStokes{I,Q,U,V} DO return the standard // deviation of the noise for that specific casacore::Stokes type. // // The casacore::ImageExpr objects returned have the brightness units and ImageInfo // set. The MiscInfo (a permanent record) and logSink are not set. // // </synopsis> // // <motivation> // Basic image analysis capability // </motivation> // <todo asof="1999/11/01"> // <li> plotting for function rotationMeasure // <li> some assessment of the curvature of pa-l**2 // </todo> class ImagePolTask : public ImageTask<casacore::Float> { public: enum StokesTypes {I, Q, U, V}; ImagePolTask() = delete; virtual ~ImagePolTask(); virtual casacore::String getClass() const; /* // Get the linearly polarized intensity image and its // standard deviation. If wish to debias the image, you // can either provide <src>sigma</src> (the standard // deviation of the termal noise ) or if <src>sigma</src> is non-positive, // it will be worked out for you with a clipped mean algorithm. // <group> casacore::ImageExpr<casacore::Float> linPolInt( casacore::Bool debias, casacore::Float clip=10.0, casacore::Float sigma=-1.0 ); */ casacore::Float sigmaLinPolInt( casacore::Float clip=10.0, casacore::Float sigma=-1.0 ); // </group> protected: ImagePolTask( const SPCIIF image, const casacore::String& outname, casacore::Bool overwrite ); casacore::Bool _checkQUBeams( casacore::Bool requireChannelEquality, casacore::Bool throws=casacore::True ) const; // Change the casacore::Stokes casacore::Coordinate for the given // complex image to be of the specified casacore::Stokes type void _fiddleStokesCoordinate( casacore::ImageInterface<casacore::Float>& ie, casacore::Stokes::StokesTypes type ) const; std::vector<casacore::Coordinate::Type> _getNecessaryCoordinates() const { static const std::vector<casacore::Coordinate::Type> v { casacore::Coordinate::STOKES }; return v; } CasacRegionManager::StokesControl _getStokesControl() const { return CasacRegionManager::USE_ALL_STOKES; } SPCIIF _getStokesImage(StokesTypes type) const; // Make a LEN for the give types of polarized intensity casacore::LatticeExprNode _makePolIntNode( casacore::Bool debias, casacore::Float clip, casacore::Float sigma, casacore::Bool doLin, casacore::Bool doCirc ); void _maskAndZeroNaNs(SPIIF out); void _setDoLinDoCirc( casacore::Bool& doLin, casacore::Bool& doCirc, casacore::Bool requireI ) const; void _setInfo( casacore::ImageInterface<Float>& im, const StokesTypes stokes ) const; private: // These blocks are always size 4, with IQUV in slots 0,1,2,3 // If your image is IV only, they still use slots 0 and 3 std::vector<SPIIF> _stokesImage = std::vector<SPIIF>(4); std::vector<std::shared_ptr<casacore::LatticeStatistics<casacore::Float>>> _stokesStats = std::vector<std::shared_ptr<casacore::LatticeStatistics<casacore::Float>>>(4); casacore::Matrix<casacore::Bool> _beamsEqMat = casacore::Matrix<casacore::Bool>(4, 4, casacore::False); Float _oldClip = 0.0; static const casacore::String CLASS_NAME; casacore::Bool _checkBeams( const std::vector<StokesTypes>& stokes, casacore::Bool requireChannelEquality, casacore::Bool throws=true ) const; casacore::Bool _checkIQUBeams( casacore::Bool requireChannelEquality, casacore::Bool throws=casacore::True ) const; casacore::Bool _checkIVBeams( casacore::Bool requireChannelEquality, casacore::Bool throws=casacore::True ) const; void _createBeamsEqMat(); // Find the casacore::Stokes in the construction image and assign pointers void _findStokes(); void _fiddleStokesCoordinate( casacore::CoordinateSystem& cSys, casacore::Stokes::StokesTypes type ) const; // Make a casacore::SubImage from the construction image for the specified pixel // along the specified pixel axis SPIIF _makeSubImage( casacore::IPosition& blc, casacore::IPosition& trc, casacore::Int axis, casacore::Int pix ) const; // Get the best estimate of the statistical noise. This gives you // the standard deviation with outliers from the mean // clipped first. The idea is to not be confused by source or dynamic range issues. // Generally casacore::Stokes V is empty of sources (not always), then Q and U are generally // less bright than I. So this function first tries V, then Q and U // and lastly I to give you its noise estimate casacore::Float _sigma (casacore::Float clip=10.0); // Find the standard deviation for the casacore::Stokes image specified by the integer index casacore::Float _sigma(StokesTypes index, casacore::Float clip); // Return I, Q, U or V for specified integer index (0-3) casacore::String _stokesName (StokesTypes index) const; }; } #endif