LCOV - code coverage report
Current view: top level - mstransform/TVI - StatWtVarianceAndWeightCalculator.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 39 43 90.7 %
Date: 2023-10-25 08:47:59 Functions: 4 5 80.0 %

          Line data    Source code
       1             : //#  CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
       2             : //#  Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All
       3             : //#  rights reserved.
       4             : //#  Copyright (C) European Southern Observatory, 2011, All rights reserved.
       5             : //#
       6             : //#  This library is free software; you can redistribute it and/or
       7             : //#  modify it under the terms of the GNU Lesser General Public
       8             : //#  License as published by the Free software Foundation; either
       9             : //#  version 2.1 of the License, or (at your option) any later version.
      10             : //#
      11             : //#  This library is distributed in the hope that it will be useful,
      12             : //#  but WITHOUT ANY WARRANTY, without even the implied warranty of
      13             : //#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             : //#  Lesser General Public License for more details.
      15             : //#
      16             : //#  You should have received a copy of the GNU Lesser General Public
      17             : //#  License along with this library; if not, write to the Free Software
      18             : //#  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      19             : //#  MA 02111-1307  USA
      20             : 
      21             : #include <mstransform/TVI/StatWtVarianceAndWeightCalculator.h>
      22             : 
      23             : #include <casacore/casa/Arrays/ArrayMath.h>
      24             : #include <casacore/casa/Arrays/Cube.h>
      25             : 
      26             : // DEBUG
      27             : #include <casacore/casa/IO/ArrayIO.h>
      28             : 
      29             : #ifdef _OPENMP
      30             : #include <omp.h>
      31             : #endif
      32             : 
      33             : using namespace casacore;
      34             : using namespace std;
      35             : 
      36             : namespace casa {
      37             : 
      38          46 : StatWtVarianceAndWeightCalculator::StatWtVarianceAndWeightCalculator(
      39             :     const shared_ptr<
      40             :         StatisticsAlgorithm<
      41             :             Double, Array<Float>::const_iterator, Array<Bool>::const_iterator,
      42             :             Array<Double>::const_iterator
      43             :         >
      44             :     > statAlg,
      45             :     shared_ptr<map<uInt, pair<uInt, uInt>>> samples, Int minSamp
      46          46 : ) : _statAlg(statAlg->clone()), _samples(samples), _minSamp(minSamp) {}
      47             : 
      48          46 : StatWtVarianceAndWeightCalculator::~StatWtVarianceAndWeightCalculator() {}
      49             : 
      50      433691 : Double StatWtVarianceAndWeightCalculator::computeVariance(
      51             :     const Cube<Complex>& data,
      52             :     const Cube<Bool>& flags, const Vector<Double>& exposures,
      53             :     casacore::uInt spw
      54             : ) const {
      55      433691 :     const auto npts = data.size();
      56      433691 :     if ((Int)npts < _minSamp || (Int)nfalse(flags) < _minSamp) {
      57             :         // not enough points, trivial
      58       77287 :         return 0;
      59             :     }
      60             :     // called in multi-threaded mode, so need to clone this for each thread
      61             :     std::unique_ptr<
      62             :         StatisticsAlgorithm<
      63             :             Double, Array<Float>::const_iterator,
      64             :             Array<Bool>::const_iterator, Array<Double>::const_iterator
      65             :         >
      66      712808 :     > statAlg(_statAlg->clone());
      67             :     // some data not flagged
      68      712808 :     const auto realPart = real(data);
      69      712808 :     const auto imagPart = imag(data);
      70      712808 :     const auto mask = ! flags;
      71      712808 :     Cube<Double> exposureCube(data.shape());
      72      356404 :     const auto nPlanes = data.nplane();
      73      990612 :     for (size_t i=0; i<nPlanes; ++i) {
      74      634208 :         exposureCube.xyPlane(i) = exposures[i];
      75             :     }
      76      712808 :     auto riter = realPart.begin();
      77      712808 :     auto iiter = imagPart.begin();
      78      712808 :     auto miter = mask.begin();
      79      712808 :     auto eiter = exposureCube.begin();
      80      356404 :     statAlg->setData(riter, eiter, miter, npts);
      81      712808 :     auto realStats = statAlg->getStatistics();
      82      356404 :     auto realVar = realStats.nvariance/realStats.npts;
      83             :     // reset data to imaginary parts
      84      356404 :     statAlg->setData(iiter, eiter, miter, npts);
      85      356404 :     auto imagStats = statAlg->getStatistics();
      86      356404 :     auto imagVar = imagStats.nvariance/imagStats.npts;
      87      356404 :     auto varSum = realVar + imagVar;
      88             :     // _samples.second can be updated in two different places, so use
      89             :     // a local (per thread) variable and update the object's private field in one
      90             :     // place
      91      356404 :     uInt updateSecond = False;
      92      356404 :     if (varSum > 0) {
      93             : #ifdef _OPENMP
      94             : #pragma omp atomic
      95             : #endif
      96      356404 :         ++((*_samples)[spw].first);
      97      356404 :         if (imagVar == 0 || realVar == 0) {
      98           0 :             updateSecond = True;
      99             :         }
     100             :         else {
     101      356404 :             auto ratio = imagVar/realVar;
     102      356404 :             auto inverse = 1/ratio;
     103      356404 :             updateSecond = ratio > 1.5 || inverse > 1.5;
     104             :         }
     105      356404 :         if (updateSecond) {
     106             : #ifdef _OPENMP
     107             : #pragma omp atomic
     108             : #endif
     109      217625 :             ++((*_samples)[spw].second);
     110             :         }
     111             :     }
     112      356404 :     return varSum/2;
     113             : }
     114             : 
     115      427529 : Double StatWtVarianceAndWeightCalculator::computeWeight(
     116             :     const Cube<Complex>& data, const Cube<Bool>& flags,
     117             :     const Vector<Double>& exposures, uInt spw, Double targetExposure
     118             : ) const {
     119      427529 :     auto varEq = computeVariance(data, flags, exposures, spw);
     120      427529 :     return varEq == 0 ? 0 : targetExposure/varEq;
     121             : }
     122             : 
     123           0 : Vector<Double> StatWtVarianceAndWeightCalculator::computeWeights(
     124             :     const Cube<Complex>& data, const Cube<Bool>& flags,
     125             :     const Vector<Double>& exposures, uInt spw
     126             : ) const {
     127           0 :     auto varEq = computeVariance(data, flags, exposures, spw);
     128           0 :     return varEq == 0 ? Vector<Double>(exposures.size(), 0) : exposures/varEq;
     129             : }
     130             : 
     131             : }

Generated by: LCOV version 1.16