LCOV - code coverage report
Current view: top level - mstransform/TVI - StatWtVarianceAndWeightCalculator.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 46 0.0 %
Date: 2024-10-09 13:55:54 Functions: 0 5 0.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           0 : 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           0 : ) : _statAlg(statAlg->clone()), _samples(samples), _minSamp(minSamp) {}
      47             : 
      48           0 : StatWtVarianceAndWeightCalculator::~StatWtVarianceAndWeightCalculator() {}
      49             : 
      50           0 : Double StatWtVarianceAndWeightCalculator::computeVariance(
      51             :     const Cube<Complex>& data,
      52             :     const Cube<Bool>& flags, const Vector<Double>& exposures,
      53             :     casacore::uInt spw
      54             : ) const {
      55           0 :     const auto npts = data.size();
      56           0 :     if ((Int)npts < _minSamp || (Int)nfalse(flags) < _minSamp) {
      57             :         // not enough points, trivial
      58           0 :         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           0 :     > statAlg(_statAlg->clone());
      67             :     // some data not flagged
      68           0 :     const auto realPart = real(data);
      69           0 :     const auto imagPart = imag(data);
      70           0 :     const auto mask = ! flags;
      71           0 :     Cube<Double> exposureCube(data.shape());
      72           0 :     const auto nPlanes = data.nplane();
      73           0 :     for (size_t i=0; i<nPlanes; ++i) {
      74           0 :         exposureCube.xyPlane(i) = exposures[i];
      75             :     }
      76           0 :     auto riter = realPart.begin();
      77           0 :     auto iiter = imagPart.begin();
      78           0 :     auto miter = mask.begin();
      79           0 :     auto eiter = exposureCube.begin();
      80           0 :     statAlg->setData(riter, eiter, miter, npts);
      81           0 :     auto realStats = statAlg->getStatistics();
      82           0 :     auto realVar = realStats.nvariance/realStats.npts;
      83             :     // reset data to imaginary parts
      84           0 :     statAlg->setData(iiter, eiter, miter, npts);
      85           0 :     auto imagStats = statAlg->getStatistics();
      86           0 :     auto imagVar = imagStats.nvariance/imagStats.npts;
      87           0 :     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           0 :     uInt updateSecond = False;
      92           0 :     if (varSum > 0) {
      93             : #ifdef _OPENMP
      94           0 : #pragma omp atomic
      95             : #endif
      96           0 :         ++((*_samples)[spw].first);
      97           0 :         if (imagVar == 0 || realVar == 0) {
      98           0 :             updateSecond = True;
      99             :         }
     100             :         else {
     101           0 :             auto ratio = imagVar/realVar;
     102           0 :             auto inverse = 1/ratio;
     103           0 :             updateSecond = ratio > 1.5 || inverse > 1.5;
     104             :         }
     105           0 :         if (updateSecond) {
     106             : #ifdef _OPENMP
     107           0 : #pragma omp atomic
     108             : #endif
     109           0 :             ++((*_samples)[spw].second);
     110             :         }
     111             :     }
     112           0 :     return varSum/2;
     113           0 : }
     114             : 
     115           0 : Double StatWtVarianceAndWeightCalculator::computeWeight(
     116             :     const Cube<Complex>& data, const Cube<Bool>& flags,
     117             :     const Vector<Double>& exposures, uInt spw, Double targetExposure
     118             : ) const {
     119           0 :     auto varEq = computeVariance(data, flags, exposures, spw);
     120           0 :     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