LCOV - code coverage report
Current view: top level - mstransform/TVI - ConvolutionTVI.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 0 152 0.0 %
Date: 2023-11-06 10:06:49 Functions: 0 30 0.0 %

          Line data    Source code
       1             : //# ConvolutionTVI.h: This file contains the implementation of the ConvolutionTVI class.
       2             : //#
       3             : //#  CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
       4             : //#  Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All rights reserved.
       5             : //#  Copyright (C) European Southern Observatory, 2011, All rights reserved.
       6             : //#
       7             : //#  This library is free software; you can redistribute it and/or
       8             : //#  modify it under the terms of the GNU Lesser General Public
       9             : //#  License as published by the Free software Foundation; either
      10             : //#  version 2.1 of the License, or (at your option) any later version.
      11             : //#
      12             : //#  This library is distributed in the hope that it will be useful,
      13             : //#  but WITHOUT ANY WARRANTY, without even the implied warranty of
      14             : //#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             : //#  Lesser General Public License for more details.
      16             : //#
      17             : //#  You should have received a copy of the GNU Lesser General Public
      18             : //#  License along with this library; if not, write to the Free Software
      19             : //#  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      20             : //#  MA 02111-1307  USA
      21             : //# $Id: $
      22             : 
      23             : #include <mstransform/TVI/ConvolutionTVI.h>
      24             : 
      25             : using namespace casacore;
      26             : namespace casa { //# NAMESPACE CASA - BEGIN
      27             : 
      28             : namespace vi { //# NAMESPACE VI - BEGIN
      29             : 
      30             : //////////////////////////////////////////////////////////////////////////
      31             : // ConvolutionTVI class
      32             : //////////////////////////////////////////////////////////////////////////
      33             : 
      34             : // -----------------------------------------------------------------------
      35             : //
      36             : // -----------------------------------------------------------------------
      37           0 : ConvolutionTVI::ConvolutionTVI( ViImplementation2 * inputVii,
      38           0 :                                                                 const Record &configuration):
      39           0 :                                                                 FreqAxisTVI (inputVii)
      40             : {
      41             :         // Parse and check configuration parameters
      42             :         // Note: if a constructor finishes by throwing an exception, the memory
      43             :         // associated with the object itself is cleaned up — there is no memory leak.
      44           0 :         if (not parseConfiguration(configuration))
      45             :         {
      46           0 :                 throw AipsError("Error parsing ConvolutionTVI configuration");
      47             :         }
      48             : 
      49           0 :         initialize();
      50             : 
      51           0 :         return;
      52             : }
      53             : 
      54             : // -----------------------------------------------------------------------
      55             : //
      56             : // -----------------------------------------------------------------------
      57           0 : Bool ConvolutionTVI::parseConfiguration(const Record &configuration)
      58             : {
      59           0 :         int exists = -1;
      60           0 :         Bool ret = true;
      61             : 
      62             :         // Parse kernel parameter (optional)
      63           0 :         exists = -1;
      64           0 :         exists = configuration.fieldNumber ("kernel");
      65           0 :         if (exists >= 0)
      66             :         {
      67           0 :                 if( configuration.type(exists) == casacore::TpArrayFloat )
      68             :                 {
      69           0 :                         convCoeff_p.resize(0,false);
      70           0 :                         convCoeff_p = configuration.asArrayFloat( exists );
      71           0 :                         logger_p << LogIO::NORMAL << LogOrigin("ConvolutionTVI", __FUNCTION__)
      72           0 :                                         << "Kernel is " << convCoeff_p << LogIO::POST;
      73             :                 }
      74             :                 else
      75             :                 {
      76           0 :                         ret = false;
      77           0 :                         logger_p << LogIO::SEVERE << LogOrigin("ConvolutionTVI", __FUNCTION__)
      78             :                                         << "Wrong format of kernel parameter (only float/double/int arrays are supported) "
      79           0 :                                         << LogIO::POST;
      80             :                 }
      81             :         }
      82             : 
      83           0 :         return ret;
      84             : }
      85             : 
      86             : // -----------------------------------------------------------------------
      87             : //
      88             : // -----------------------------------------------------------------------
      89           0 : void ConvolutionTVI::initialize()
      90             : {
      91             :         // Populate nchan input-output maps
      92             :         Int spw;
      93           0 :         uInt spw_idx = 0;
      94           0 :         map<Int,vector<Int> >::iterator iter;
      95           0 :         for(iter=spwInpChanIdxMap_p.begin();iter!=spwInpChanIdxMap_p.end();iter++)
      96             :         {
      97           0 :                 spw = iter->first;
      98           0 :                 spwOutChanNumMap_p[spw] = spwInpChanIdxMap_p[spw].size();
      99             : 
     100           0 :                 spw_idx++;
     101             :         }
     102             : 
     103           0 :         return;
     104             : }
     105             : 
     106             : // -----------------------------------------------------------------------
     107             : //
     108             : // -----------------------------------------------------------------------
     109           0 : void ConvolutionTVI::flag(Cube<Bool>& flagCube) const
     110             : {
     111             :         // Get input VisBuffer and SPW
     112           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     113             : 
     114             :         // Configure Transformation Engine
     115           0 :         ConvolutionLogicalORKernel<Bool> kernel(&convCoeff_p);
     116           0 :         ConvolutionTransformEngine<Bool> transformer(&kernel,convCoeff_p.size());
     117             : 
     118             :         // Transform data
     119           0 :         transformFreqAxis(vb->flagCube(),flagCube,transformer);
     120             : 
     121           0 :         return;
     122             : }
     123             : 
     124             : // -----------------------------------------------------------------------
     125             : //
     126             : // -----------------------------------------------------------------------
     127           0 : void ConvolutionTVI::floatData (Cube<Float> & vis) const
     128             : {
     129             :         // Get input VisBuffer and SPW
     130           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     131             : 
     132             :         // Configure Transformation Engine
     133           0 :         ConvolutionDataKernel<Float> kernel(&convCoeff_p);
     134           0 :         ConvolutionTransformEngine<Float> transformer(&kernel,convCoeff_p.size());
     135             : 
     136             :         // Transform data
     137           0 :         transformFreqAxis(vb->visCubeFloat(),vis,transformer);
     138             : 
     139           0 :         return;
     140             : }
     141             : 
     142             : // -----------------------------------------------------------------------
     143             : //
     144             : // -----------------------------------------------------------------------
     145           0 : void ConvolutionTVI::visibilityObserved (Cube<Complex> & vis) const
     146             : {
     147             :         // Get input VisBuffer and SPW
     148           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     149             : 
     150             :         // Configure Transformation Engine
     151           0 :         ConvolutionDataKernel<Complex> kernel(&convCoeff_p);
     152           0 :         ConvolutionTransformEngine<Complex> transformer(&kernel,convCoeff_p.size());
     153             : 
     154             :         // Transform data
     155           0 :         transformFreqAxis(vb->visCube(),vis,transformer);
     156             : 
     157           0 :         return;
     158             : }
     159             : 
     160             : // -----------------------------------------------------------------------
     161             : //
     162             : // -----------------------------------------------------------------------
     163           0 : void ConvolutionTVI::visibilityCorrected (Cube<Complex> & vis) const
     164             : {
     165             :         // Get input VisBuffer and SPW
     166           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     167             : 
     168             :         // Configure Transformation Engine
     169           0 :         ConvolutionDataKernel<Complex> kernel(&convCoeff_p);
     170           0 :         ConvolutionTransformEngine<Complex> transformer(&kernel,convCoeff_p.size());
     171             : 
     172             :         // Transform data
     173           0 :         transformFreqAxis(vb->visCubeCorrected(),vis,transformer);
     174             : 
     175           0 :         return;
     176             : }
     177             : 
     178             : // -----------------------------------------------------------------------
     179             : //
     180             : // -----------------------------------------------------------------------
     181           0 : void ConvolutionTVI::visibilityModel (Cube<Complex> & vis) const
     182             : {
     183             :         // Get input VisBuffer and SPW
     184           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     185             : 
     186             :         // Configure Transformation Engine
     187           0 :         ConvolutionDataKernel<Complex> kernel(&convCoeff_p);
     188           0 :         ConvolutionTransformEngine<Complex> transformer(&kernel,convCoeff_p.size());
     189             : 
     190             :         // Transform data
     191           0 :         transformFreqAxis(vb->visCubeModel(),vis,transformer);
     192             : 
     193           0 :         return;
     194             : }
     195             : 
     196             : // -----------------------------------------------------------------------
     197             : //
     198             : // -----------------------------------------------------------------------
     199           0 : void ConvolutionTVI::weightSpectrum(Cube<Float> &weightSp) const
     200             : {
     201             :         // Get input VisBuffer and SPW
     202           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     203             : 
     204             :         // Configure Transformation Engine
     205           0 :         ConvolutionWeightPropagationKernel<Float> kernel(&convCoeff_p);
     206           0 :         ConvolutionTransformEngine<Float> transformer(&kernel,convCoeff_p.size());
     207             : 
     208             :         // Transform data
     209           0 :         transformFreqAxis(vb->weightSpectrum(),weightSp,transformer);
     210             : 
     211           0 :         return;
     212             : }
     213             : 
     214             : // -----------------------------------------------------------------------
     215             : //
     216             : // -----------------------------------------------------------------------
     217           0 : void ConvolutionTVI::sigmaSpectrum(Cube<Float> &sigmaSp) const
     218             : {
     219             :         // Get input VisBuffer and SPW
     220           0 :         VisBuffer2 *vb = getVii()->getVisBuffer();
     221             : 
     222             :         // Configure Transformation Engine
     223           0 :         ConvolutionWeightPropagationKernel<Float> kernel(&convCoeff_p);
     224           0 :         ConvolutionTransformEngine<Float> transformer(&kernel,convCoeff_p.size());
     225             : 
     226             :         // Get weightSpectrum from sigmaSpectrum
     227           0 :         Cube<Float> weightSpFromSigmaSp;
     228           0 :         weightSpFromSigmaSp.resize(vb->sigmaSpectrum().shape(),false);
     229           0 :         weightSpFromSigmaSp = vb->sigmaSpectrum(); // = Operator makes a copy
     230           0 :         arrayTransformInPlace (weightSpFromSigmaSp,sigmaToWeight);
     231             : 
     232             :         // Transform data
     233           0 :         transformFreqAxis(weightSpFromSigmaSp,sigmaSp,transformer);
     234             : 
     235             :         // Transform back from weight format to sigma format
     236           0 :         arrayTransformInPlace (sigmaSp,weightToSigma);
     237             : 
     238           0 :         return;
     239             : }
     240             : 
     241             : //////////////////////////////////////////////////////////////////////////
     242             : // ConvolutionTVIFactory class
     243             : //////////////////////////////////////////////////////////////////////////
     244             : 
     245             : // -----------------------------------------------------------------------
     246             : //
     247             : // -----------------------------------------------------------------------
     248           0 : ConvolutionTVIFactory::ConvolutionTVIFactory (Record &configuration,
     249           0 :                                                                                                         ViImplementation2 *inputVii)
     250             : {
     251           0 :         inputVii_p = inputVii;
     252           0 :         configuration_p = configuration;
     253           0 : }
     254             : 
     255             : // -----------------------------------------------------------------------
     256             : //
     257             : // -----------------------------------------------------------------------
     258           0 : vi::ViImplementation2 * ConvolutionTVIFactory::createVi(VisibilityIterator2 *) const
     259             : {
     260           0 :         return new ConvolutionTVI(inputVii_p,configuration_p);
     261             : }
     262             : 
     263             : // -----------------------------------------------------------------------
     264             : //
     265             : // -----------------------------------------------------------------------
     266           0 : vi::ViImplementation2 * ConvolutionTVIFactory::createVi() const
     267             : {
     268           0 :         return new ConvolutionTVI(inputVii_p,configuration_p);
     269             : }
     270             : 
     271             : //////////////////////////////////////////////////////////////////////////
     272             : // ConvolutionTransformEngine class
     273             : //////////////////////////////////////////////////////////////////////////
     274             : 
     275             : // -----------------------------------------------------------------------
     276             : //
     277             : // -----------------------------------------------------------------------
     278           0 : template<class T> ConvolutionTransformEngine<T>::ConvolutionTransformEngine
     279             :                                                                                                 (ConvolutionKernel<T> *kernel,
     280           0 :                                                                                                 uInt width)
     281             : {
     282           0 :         width_p = width;
     283           0 :         convolutionKernel_p = kernel;
     284           0 : }
     285             : 
     286             : // -----------------------------------------------------------------------
     287             : //
     288             : // -----------------------------------------------------------------------
     289           0 : template<class T> void ConvolutionTransformEngine<T>::transform(Vector<T> &inputVector,
     290             :                                                                                                                                 Vector<T> &outputVector)
     291             : {
     292           0 :         uInt startChanIndex = 0;
     293           0 :         uInt outChanStart = width_p / 2;
     294           0 :         uInt outChanIndex = outChanStart;
     295           0 :         uInt outChanStop = inputVector.size() - width_p / 2;
     296           0 :         while (startChanIndex < outChanStop)
     297             :         {
     298           0 :                 convolutionKernel_p->kernel(inputVector,outputVector,startChanIndex,outChanIndex);
     299           0 :                 startChanIndex += 1;
     300           0 :                 outChanIndex += 1;
     301             :         }
     302             : 
     303             :         // Process low end
     304           0 :         for (uInt chanIndex = 0; chanIndex<outChanStart; chanIndex++)
     305             :         {
     306           0 :                 convolutionKernel_p->kernel(inputVector,outputVector,chanIndex,chanIndex);
     307           0 :                 chanIndex += 1;
     308             :         }
     309             : 
     310             :         // Process high end
     311           0 :         for (uInt chanIndex = outChanStop; chanIndex<inputVector.size(); chanIndex++)
     312             :         {
     313           0 :                 convolutionKernel_p->kernel(inputVector,outputVector,chanIndex,chanIndex);
     314           0 :                 chanIndex += 1;
     315             :         }
     316             : 
     317           0 :         return;
     318             : }
     319             : 
     320             : //////////////////////////////////////////////////////////////////////////
     321             : // ConvolutionKernel class
     322             : //////////////////////////////////////////////////////////////////////////
     323           0 : template<class T> ConvolutionKernel<T>::ConvolutionKernel(Vector<Float> *convCoeff)
     324             : {
     325           0 :         convCoeff_p = convCoeff;
     326           0 :         width_p = convCoeff->size();
     327           0 : }
     328             : 
     329             : //////////////////////////////////////////////////////////////////////////
     330             : // ConvolutionDataKernel class
     331             : //////////////////////////////////////////////////////////////////////////
     332             : 
     333             : // -----------------------------------------------------------------------
     334             : //
     335             : // -----------------------------------------------------------------------
     336           0 : template<class T> ConvolutionDataKernel<T>::ConvolutionDataKernel(Vector<Float> *convCoeff):
     337           0 :                 ConvolutionKernel<T>(convCoeff)
     338             : {
     339             : 
     340           0 : }
     341             : 
     342             : // -----------------------------------------------------------------------
     343             : //
     344             : // -----------------------------------------------------------------------
     345           0 : template<class T> void ConvolutionDataKernel<T>::kernel(    Vector<T> &inputVector,
     346             :                                                                                                                         Vector<T> &outputVector,
     347             :                                                                                                                         uInt startInputPos,
     348             :                                                                                                                         uInt outputPos)
     349             : {
     350             :         // Do not process edges
     351           0 :         if (startInputPos == outputPos)
     352             :         {
     353           0 :                 outputVector(outputPos) = inputVector(startInputPos);
     354           0 :                 return;
     355             :         }
     356             : 
     357             :         // Initialization
     358           0 :         outputVector(outputPos) = (*convCoeff_p)(0)*inputVector(startInputPos);
     359             : 
     360             :         // Main loop
     361           0 :         for (uInt chanIndex = 1; chanIndex<width_p; chanIndex++)
     362             :         {
     363           0 :                 outputVector(outputPos) += (*convCoeff_p)(chanIndex)*inputVector(startInputPos+chanIndex);
     364             :         }
     365             : 
     366           0 :         return;
     367             : }
     368             : 
     369             : //////////////////////////////////////////////////////////////////////////
     370             : // ConvolutionLogicalORKernel class
     371             : //////////////////////////////////////////////////////////////////////////
     372             : 
     373             : // -----------------------------------------------------------------------
     374             : //
     375             : // -----------------------------------------------------------------------
     376           0 : template<class T> ConvolutionLogicalORKernel<T>::ConvolutionLogicalORKernel(Vector<Float> *convCoeff):
     377           0 :                 ConvolutionKernel<T>(convCoeff)
     378             : {
     379             : 
     380             : 
     381           0 : }
     382             : 
     383             : // -----------------------------------------------------------------------
     384             : //
     385             : // -----------------------------------------------------------------------
     386           0 : template<class T> void ConvolutionLogicalORKernel<T>::kernel(       Vector<T> &inputVector,
     387             :                                                                                                                                 Vector<T> &outputVector,
     388             :                                                                                                                                 uInt startInputPos,
     389             :                                                                                                                                 uInt outputPos)
     390             : {
     391             :         // Flag edges
     392           0 :         if (startInputPos == outputPos)
     393             :         {
     394           0 :                 outputVector(outputPos) = true;
     395           0 :                 return;
     396             :         }
     397             : 
     398           0 :         Bool outputFlag = false;
     399             :         // Output sample is flagged if any of the contributors are flagged
     400           0 :         for (uInt chanIndex = 0; chanIndex<width_p; chanIndex++)
     401             :         {
     402           0 :                 if (inputVector(startInputPos+chanIndex))
     403             :                 {
     404           0 :                         outputFlag = true;
     405           0 :                         break;
     406             :                 }
     407             :         }
     408             : 
     409           0 :         outputVector(outputPos) = outputFlag;
     410             : 
     411           0 :         return;
     412             : }
     413             : 
     414             : //////////////////////////////////////////////////////////////////////////
     415             : // ConvolutionWeightPropagationKernel class
     416             : //////////////////////////////////////////////////////////////////////////
     417             : 
     418             : // -----------------------------------------------------------------------
     419             : //
     420             : // -----------------------------------------------------------------------
     421           0 : template<class T> ConvolutionWeightPropagationKernel<T>::ConvolutionWeightPropagationKernel(Vector<Float> *convCoeff):
     422           0 :                 ConvolutionKernel<T>(convCoeff)
     423             : {
     424             : 
     425           0 : }
     426             : 
     427             : // -----------------------------------------------------------------------
     428             : //
     429             : // -----------------------------------------------------------------------
     430           0 : template<class T> void ConvolutionWeightPropagationKernel<T>::kernel(       Vector<T> &inputVector,
     431             :                                                                                                                                                 Vector<T> &outputVector,
     432             :                                                                                                                                                 uInt startInputPos,
     433             :                                                                                                                                                 uInt outputPos)
     434             : {
     435             :         // Do not process edges
     436           0 :         if (startInputPos == outputPos)
     437             :         {
     438           0 :                 outputVector(outputPos) = inputVector(startInputPos);
     439           0 :                 return;
     440             :         }
     441             : 
     442             :         // Initialization (mind for zeros as there is a division operation)
     443           0 :         outputVector(outputPos) = 0;
     444           0 :         if (inputVector(startInputPos) > FLT_MIN)
     445             :         {
     446           0 :                 outputVector(outputPos) = (*convCoeff_p)(0)*(*convCoeff_p)(0)/inputVector(startInputPos);
     447             :         }
     448             : 
     449             :         // Main accumulation loop
     450           0 :         for (uInt chanIndex = 1; chanIndex<width_p; chanIndex++)
     451             :         {
     452             :                 // Mind for zeros as there is a division operation
     453           0 :                 if (inputVector(startInputPos+chanIndex) > FLT_MIN)
     454             :                 {
     455           0 :                         outputVector(outputPos) += (*convCoeff_p)(chanIndex)*(*convCoeff_p)(chanIndex)/inputVector(startInputPos+chanIndex);
     456             :                 }
     457             :         }
     458             : 
     459             :         // Final propagated weight is the inverse of the accumulation
     460           0 :         if (outputVector(outputPos) > FLT_MIN)
     461             :         {
     462           0 :                 outputVector(outputPos) = 1/outputVector(outputPos);
     463             :         }
     464             : 
     465           0 :         return;
     466             : }
     467             : 
     468             : } //# NAMESPACE VI - END
     469             : 
     470             : } //# NAMESPACE CASA - END
     471             : 
     472             : 

Generated by: LCOV version 1.16