LCOV - code coverage report
Current view: top level - synthesis/MeasurementEquations - LatConvEquation.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 51 99 51.5 %
Date: 2024-12-11 20:54:31 Functions: 8 10 80.0 %

          Line data    Source code
       1             : //# LatConvEquation.cc:  this defines LatConvEquation
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2003
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : #include <synthesis/MeasurementEquations/LatConvEquation.h>
      29             : #include <synthesis/MeasurementEquations/LinearModel.h>
      30             : #include <casacore/lattices/LEL/LatticeExpr.h>
      31             : #include <casacore/lattices/LEL/LatticeExprNode.h>
      32             : #include <casacore/lattices/Lattices/SubLattice.h>
      33             : #include <casacore/lattices/LRegions/LCBox.h>
      34             : #include <casacore/casa/Utilities/Assert.h>
      35             : #include <casacore/casa/Arrays/Vector.h>
      36             : #include <casacore/casa/Arrays/Array.h>
      37             : #include <casacore/casa/Arrays/ArrayMath.h>
      38             : #include <casacore/casa/Arrays/IPosition.h>
      39             : #include <casacore/casa/Exceptions/Error.h>
      40             : 
      41             : using namespace casacore;
      42             : namespace casa { //# NAMESPACE CASA - BEGIN
      43             : 
      44         122 : LatConvEquation::LatConvEquation(Lattice<Float> & psf, 
      45         122 :                                  Lattice<Float> & dirtyImage)
      46         122 :   :itsMeas(&dirtyImage),
      47         122 :    itsPsf(&psf),
      48         122 :    itsConv(psf, dirtyImage.shape(), true)
      49             : {
      50         122 :   itsVirgin = true;
      51         122 :   itsRealPsfSize = psf.shape();
      52         122 :   itsPsfOrigin = itsPsf->shape()/2;  
      53         122 : }
      54             : 
      55         122 : LatConvEquation::~LatConvEquation() {
      56         122 :   if (!itsVirgin) {
      57             :     //    cout << "Deleting nonVirgin PSF" << endl;
      58           0 :     delete itsPsf;
      59             :   }
      60         122 : }
      61             : 
      62         590 : Bool LatConvEquation::evaluate(Lattice<Float> & result, 
      63             :                                const LinearModel<Lattice<Float> > & model){
      64         590 :   const Lattice<Float> & modelLattice = model.getModel();
      65             :   //  DebugAssert(modelLattice.shape().isEqual(result.shape()), AipsError);
      66         590 :   itsConv.linear(result, modelLattice); 
      67         590 :   return true;
      68             : }
      69             : 
      70             : 
      71             : Lattice<Float> * 
      72         234 : LatConvEquation::evaluate(const IPosition & position, 
      73             :                           const Float amplitude,
      74             :                           const IPosition & modelSize){
      75         234 :   if (itsPsf->nelements() == 0){
      76           0 :     itsConv.getPsf(*itsPsf);
      77           0 :     itsPsfOrigin = itsPsf->shape()/2;
      78           0 :     itsRealPsfSize = itsPsf->shape();
      79             :   }
      80         234 :   IPosition psfSize = itsPsf->shape();
      81         234 :   IPosition blc = itsPsfOrigin - position;
      82         234 :   IPosition trc = blc + modelSize - 1;
      83             :   // Check if the required bounds are outside the psf. If they are then
      84             :   // resize the psf (with zero padding) to encompass the requested
      85             :   // convolution.  Another way to do this is to just return the required
      86             :   // portion of the psf (of size modelSize) suitably padded. This will be
      87             :   // quicker and more memory efficient for just one evaluation, but if the
      88             :   // user is cleaning near the edges of their image, then it will have to be
      89             :   // done for each iteration that is near the edge. By resizing the whole
      90             :   // psf when necessary it will after a few resizes be at the required size
      91             :   // for all the iterations.
      92             :   //
      93             :   // If we resize the psf and itsVirgin == true, we need to create a new psf and
      94             :   // make sure itsVirgin = false
      95             :   //
      96         702 :   if ((min(blc.asVector()) < 0) || 
      97         468 :       (max((trc-psfSize).asVector()) >= 0))
      98             :     {
      99             :       
     100             : 
     101             :       // newtrc and newblc are the points in the newPsf that
     102             :       // refer to the old Psf (itsPsf).
     103           0 :       IPosition newSize(itsPsf->ndim(), 0);
     104           0 :       IPosition newtrc(itsPsf->ndim(), 0);
     105           0 :       IPosition newblc(itsPsf->ndim(), 0);
     106           0 :       for(uInt i = 0; i < itsPsf->ndim(); i++){
     107           0 :         newblc(i) = - min(blc(i), 0);
     108           0 :         newSize(i) = std::max(trc(i)+1, psfSize(i)) + newblc(i);
     109           0 :         newtrc(i) = newblc(i) + psfSize(i) - 1;
     110             :       }
     111             :       {
     112             :         // expand/pad itsPsf
     113             :         Lattice<Float> *newPsf;
     114           0 :         newPsf = new TempLattice<Float>(newSize);
     115           0 :         newPsf->set(0.0);
     116           0 :         LCBox box(newblc,newtrc,newSize);
     117           0 :         SubLattice<Float>  newPsfSub (*newPsf, box, true);
     118           0 :         newPsfSub.copyData(*itsPsf);  // fill the old Psf into the larger new one
     119             : 
     120           0 :         if (itsVirgin) {
     121             :           // just drop old itsPsf; someone else is responcible
     122           0 :           itsPsf = newPsf;
     123           0 :           itsVirgin = false;
     124             :         } else {
     125             :           // we must clean up old itsPsf
     126           0 :           delete itsPsf;
     127           0 :           itsPsf = newPsf;
     128             :         }
     129           0 :       }
     130           0 :       itsPsfOrigin = itsPsfOrigin + newblc;
     131           0 :       LCBox box(blc+newblc, trc+newtrc, newSize);
     132           0 :       Lattice<Float> *result = 0;
     133           0 :       if (!nearAbs(Double(amplitude),1.0)) {
     134           0 :         SubLattice<Float>  newPsfSub( *itsPsf, box, true);
     135           0 :         result = new TempLattice<Float>(newPsfSub.shape());
     136           0 :         result->copyData((LatticeExpr<Float>)((amplitude) * newPsfSub ));      
     137           0 :       } else {
     138           0 :         result = new  SubLattice<Float>( *itsPsf, box, true);
     139             :       }
     140           0 :       return result;
     141           0 :     }  else {
     142         234 :       LCBox box(blc,trc,itsPsf->shape());
     143         234 :       Lattice<Float> *result = 0;
     144         234 :       if (!nearAbs(Double(amplitude),1.0)) {
     145           0 :         SubLattice<Float>  newPsfSub( *itsPsf, box, true);
     146           0 :         result = new TempLattice<Float>(newPsfSub.shape());
     147           0 :         result->copyData((LatticeExpr<Float>)((amplitude) * newPsfSub ));      
     148           0 :       } else {
     149         234 :         result = new  SubLattice<Float>( *itsPsf, box, true);
     150             :       }
     151         234 :       return result;
     152         234 :     }
     153         234 : };
     154             : 
     155             : 
     156         120 : Bool LatConvEquation::evaluate(Array<Float> & result, 
     157             :                                const IPosition & position, 
     158             :                                const Float amplitude,
     159             :                                const IPosition & modelSize)
     160             : {
     161         120 :   Lattice<Float> *resultLattice = 0;
     162         120 :   resultLattice = evaluate(position, amplitude, modelSize);
     163         120 :   if (resultLattice != 0) {
     164         120 :     result = resultLattice->get();
     165         120 :     delete resultLattice; resultLattice=0;
     166         120 :     return true;
     167             :   } else {
     168           0 :     return false;
     169             :   }
     170             : };
     171             : 
     172             : 
     173         558 : Bool LatConvEquation::residual(Lattice<Float> & result, 
     174             :                                const LinearModel< Lattice<Float> > & model) {
     175             : 
     176         558 :   if (evaluate(result, model)) {
     177        1116 :     LatticeExpr<Float> expr = *itsMeas - result;
     178         558 :     result.copyData(expr);
     179         558 :     return true;
     180         558 :   }
     181           0 :   return false;
     182             : }
     183             : 
     184             : 
     185          16 : Bool LatConvEquation::residual(Lattice<Float> & result, 
     186             :                                Float & chisq,
     187             :                                const LinearModel<Lattice<Float> > & model) {
     188          16 :   if (residual(result, model)) {
     189          32 :     LatticeExprNode myChisq = sum(result * result);
     190          16 :     chisq = myChisq.getFloat();
     191          16 :     return true;
     192          16 :   }
     193           0 :   return false;
     194             : }
     195             : 
     196             : 
     197           0 : Bool LatConvEquation::residual(Lattice<Float> & result, 
     198             :                                Float & chisq,
     199             :                                Lattice<Float> & mask,
     200             :                                const LinearModel<Lattice<Float> > & model) {
     201           0 :   if (residual(result, model)) {
     202           0 :     result.copyData( (LatticeExpr<Float>) (result * mask) );
     203           0 :     LatticeExprNode myChisq = sum(result * result);
     204           0 :     chisq = myChisq.getFloat();
     205           0 :     return true;
     206           0 :   }
     207           0 :   return false;
     208             : }
     209             : 
     210         120 : IPosition LatConvEquation::psfSize() {
     211         120 :   return itsConv.psfShape();
     212             : }
     213             : 
     214             : } //# NAMESPACE CASA - END
     215             : 

Generated by: LCOV version 1.16