LCOV - code coverage report
Current view: top level - synthesis/TransformMachines - PBMath1D.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 221 574 38.5 %
Date: 2024-10-04 18:58:15 Functions: 8 18 44.4 %

          Line data    Source code
       1             : //# PBMath1D.cc: Implementation for PBMath1D
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,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 adressed 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             : //#
      27             : //# $Id$
      28             :  
      29             : #include <casacore/casa/aips.h>
      30             : #include <casacore/casa/BasicSL/Complex.h>
      31             : #include <casacore/casa/Arrays/Matrix.h>
      32             : #include <casacore/casa/Arrays/Vector.h>
      33             : #include <synthesis/TransformMachines/PBMath1D.h>
      34             : 
      35             : #include <casacore/images/Regions/ImageRegion.h>
      36             : #include <casacore/images/Images/ImageInterface.h>
      37             : 
      38             : #include <components/ComponentModels/SkyComponent.h>
      39             : #include <components/ComponentModels/Flux.h>
      40             : #include <components/ComponentModels/ComponentShape.h>
      41             : 
      42             : #include <casacore/lattices/Lattices/LatticeIterator.h>
      43             : #include <casacore/lattices/Lattices/LatticeStepper.h>
      44             : #include <casacore/lattices/LRegions/LCSlicer.h>
      45             : #include <casacore/casa/Arrays/IPosition.h>
      46             : 
      47             : #include <casacore/measures/Measures.h>
      48             : #include <casacore/measures/Measures/MeasConvert.h>
      49             : 
      50             : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
      51             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      52             : #include <casacore/coordinates/Coordinates/SpectralCoordinate.h>
      53             : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
      54             : #include <casacore/coordinates/Coordinates/Projection.h>
      55             : #include <casacore/coordinates/Coordinates/CoordinateUtil.h>
      56             : 
      57             : #include <casacore/casa/BasicSL/String.h>
      58             : #include <casacore/casa/Utilities/Assert.h>
      59             : #include <casacore/casa/Exceptions/Error.h>
      60             : 
      61             : 
      62             : 
      63             : using namespace casacore;
      64             : namespace casa { //# NAMESPACE CASA - BEGIN
      65             : 
      66           0 : PBMath1D::PBMath1D()
      67           0 :   : composite_p(2048)
      68             : {
      69           0 : };
      70             : 
      71             : 
      72          22 : PBMath1D::PBMath1D(Quantity maximumRadius,
      73             :                    Quantity refFreq,
      74             :                    Bool isThisVP,
      75             :                    BeamSquint squint,
      76          22 :                    Bool useSymmetricBeam) :
      77             :   PBMathInterface(isThisVP, squint, useSymmetricBeam),
      78          22 :   wideFit_p(false),maximumRadius_p(maximumRadius),
      79          22 :   refFreq_p(refFreq),
      80          44 :   composite_p(2048)
      81             : {
      82          22 :   fScale_p = refFreq_p.getValue("GHz");  // scale is ratio of refFreq_p to 1GHz
      83          22 :   refFreq_p = Quantity( 1.0, "GHz");  // internal Ref Freq is now 1GHz
      84             :   // convert instantiation parameters to GHz*arcmin reference
      85          22 :   maximumRadius_p = maximumRadius_p * fScale_p;
      86          22 :   scale_p = 1.0/(C::arcmin * C::giga);
      87          22 : };
      88             : 
      89          22 : PBMath1D::~PBMath1D()
      90             : {
      91          22 : };
      92             : 
      93             : 
      94             : 
      95             : 
      96             : ImageRegion* 
      97           0 : PBMath1D::extent (const ImageInterface<Complex>& in, const MDirection& pointDir,
      98             :                   const Int row, const Float fPad,  const Int iChan,  
      99             :                   const SkyJones::SizeType sizeType)
     100             : {
     101             :   if (row) {} // Not used yet
     102             : 
     103           0 :   CoordinateSystem  coords=in.coordinates();  
     104             : 
     105           0 :   Vector<Float> blc(4);
     106           0 :   Vector<Float> trc(4);
     107           0 :   blc.set(0.0);
     108           0 :   trc.set(0.0);
     109             :   {
     110             :     Int stokesIndex, k1, k2;
     111           0 :     CoordinateUtil::findStokesAxis(stokesIndex, k1, k2, coords);
     112           0 :     blc(stokesIndex) = 0.0;
     113           0 :     trc(stokesIndex) = in.shape()(stokesIndex)-1;
     114           0 :     Int spectralIndex=CoordinateUtil::findSpectralAxis(coords); 
     115           0 :     blc(spectralIndex) = 0.0;
     116           0 :     trc(spectralIndex) = in.shape()(spectralIndex)-1;
     117             :   }
     118           0 :   extentguts(coords,  pointDir, fPad, iChan, blc, trc);
     119           0 :   refineSize(blc, trc, in.shape(), sizeType);
     120           0 :   LCSlicer lcs( blc, trc );
     121           0 :   return  ( new ImageRegion(lcs) );
     122           0 : };
     123             : ImageRegion* 
     124           0 : PBMath1D::extent (const ImageInterface<Float>& in, const MDirection& pointDir,
     125             :                   const Int row, const Float fPad, const Int iChan, 
     126             :                   const SkyJones::SizeType sizeType)
     127             : {
     128             :   if (row) {} // unused
     129           0 :   CoordinateSystem  coords=in.coordinates();
     130           0 :   Vector<Float> blc(4);
     131           0 :   Vector<Float> trc(4);
     132           0 :   blc.set(0.0);
     133           0 :   trc.set(0.0);
     134             :   {
     135             :     Int stokesIndex, k1, k2;
     136           0 :     CoordinateUtil::findStokesAxis(stokesIndex, k1, k2, coords);
     137           0 :     blc(stokesIndex) = 0.0;
     138           0 :     trc(stokesIndex) = in.shape()(stokesIndex)-1;
     139           0 :     Int spectralIndex=CoordinateUtil::findSpectralAxis(coords);
     140           0 :     blc(spectralIndex) = 0.0;
     141           0 :     trc(spectralIndex) = in.shape()(spectralIndex)-1;
     142             :   }
     143           0 :   extentguts(coords,  pointDir, fPad, iChan, blc, trc);
     144           0 :   refineSize(blc, trc, in.shape(), sizeType);
     145           0 :   LCSlicer lcs( blc, trc );
     146           0 :   return  ( new ImageRegion(lcs) );
     147           0 : };
     148             : 
     149             : 
     150             : 
     151           8 : Int PBMath1D::support(const CoordinateSystem& cs){
     152           8 : Int directionIndex=cs.findCoordinate(Coordinate::DIRECTION);
     153           8 :  AlwaysAssert(directionIndex>=0, AipsError);
     154             :  DirectionCoordinate
     155           8 :    directionCoord=cs.directionCoordinate(directionIndex);
     156             :  
     157           8 :  Vector<String> dirunit=directionCoord.worldAxisUnits();
     158             : 
     159             :  Double freq;
     160             :  {
     161           8 :    Int spectralIndex=cs.findCoordinate(Coordinate::SPECTRAL);
     162           8 :    AlwaysAssert(spectralIndex>=0, AipsError);
     163             :    SpectralCoordinate
     164           8 :      spectralCoord=cs.spectralCoordinate(spectralIndex);
     165             : 
     166             :    
     167           8 :    Vector<String> units(1);
     168           8 :    units = "Hz";
     169           8 :    spectralCoord.setWorldAxisUnits(units);
     170             : 
     171           8 :    Vector<Double> spectralWorld(1);
     172           8 :    Vector<Double> spectralPixel(1);
     173           8 :    spectralPixel(0) = 0;
     174           8 :    spectralCoord.toWorld(spectralWorld, spectralPixel);  
     175           8 :    freq  = spectralWorld(0);
     176           8 :   }
     177             : 
     178             : 
     179             : 
     180             :   // maximumRadius_p: maximum radius at 1 GHz frequency
     181             :   //Double delta = maximumRadius_p.getValue("rad") *  1.0e+9 / freq;
     182             : 
     183             : 
     184             :   //Number of pix at freq
     185           8 :   Double numpix=maximumRadius_p.getValue(dirunit(0))/fabs(directionCoord.increment()(0))*2.0*1.0e9/freq ;
     186             :   
     187             :  
     188           8 :   return Int(floor(numpix));
     189             : 
     190             : 
     191           8 : }
     192           0 : void  PBMath1D::refineSize(Vector<Float>& blc, Vector<Float>& trc, const IPosition& shape, 
     193             :                             SkyJones::SizeType sizeType)
     194             : {
     195             :   // Round Down and Up for BLC and TRC, make them integers
     196           0 :   Vector<Bool> blcTrouble(blc.nelements(), false);
     197           0 :   Vector<Bool> trcTrouble(blc.nelements(), false);
     198           0 :   Vector<Float> d1(2);
     199           0 :   Vector<Float> d2(2);
     200             : 
     201           0 :   for (Int i=0; i<2; i++) {
     202             : 
     203           0 :     blc(i) = (Int)(blc(i));
     204           0 :     trc(i) = (Int)(trc(i)+0.99);  // OK, its ALMOST rounding up    
     205             : 
     206           0 :    if (blc(i) < 0) {
     207           0 :       blc(i) = 0;
     208           0 :       blcTrouble(i) = true;
     209             :     }
     210           0 :    if (trc(i) > shape(i)-1) {
     211           0 :       trc(i) = shape(i)-1;
     212           0 :       trcTrouble(i) = true;
     213             :     }
     214             : 
     215           0 :     d1(i) = trc(i) - blc(i) + 1;
     216             : 
     217           0 :     if (sizeType == SkyJones::POWEROF2) {
     218           0 :       d2(i) = (Int)( pow( 2.0, (Double)(Int)(log((Double)d1(i))/log(2.0) + 1.0) )+0.01);
     219           0 :     } else if (sizeType == SkyJones::COMPOSITE) {
     220           0 :       d2(i) = composite_p.nextLarger( (Int)d1(i) );      
     221             :     } else {
     222           0 :       d2(i) = d1(i);
     223             :     }
     224             : 
     225             :     // Deal with cases:
     226             : 
     227           0 :     if (d2(i) >= shape(i)) {
     228             :       // requested size doesn't even fit into image:
     229             :       // ----- revert to image size
     230           0 :       blc(i) = 0; trc(i) = shape(i)-1;
     231             : 
     232           0 :     } else if (blcTrouble(i)) {
     233             :       // requseted size fits, but buts up against the "bottom";
     234             :       // ----- make full adjustment to the "top"
     235           0 :       blc(i) = 0; trc(i) = d2(i)-1;
     236             : 
     237           0 :     } else if (trcTrouble(i)) {
     238             :       // requseted size fits, but buts up against the "top";
     239             :       // ----- make full adjustment to the "bottom"
     240           0 :       trc(i) = shape(i)-1;  blc(i) = shape(i) - d2(i);
     241             : 
     242             :     } else {
     243             :       // requested subimage does not exceed starting image
     244             :       // ----- do appropriate thing, based on even or odd
     245           0 :       Float diff = d2(i) - d1(i);
     246           0 :       Bool even = (Bool)( (Int)diff == 2 * (Int)(diff/2) );
     247           0 :       if (even) {
     248           0 :         blc(i) = blc(i) - diff/2;
     249           0 :         trc(i) = trc(i) + diff/2;
     250             :       } else {
     251           0 :         blc(i) = blc(i) - diff/2 + 0.5;
     252           0 :         trc(i) = trc(i) + diff/2 + 0.5;
     253             :       }
     254             :     }
     255             :   }
     256           0 : };
     257             : 
     258             : 
     259             : 
     260             : 
     261             : void
     262           0 : PBMath1D::extentguts (const CoordinateSystem& coords, const MDirection& pointDir,
     263             :                   const Float fPad, const Int iChan, Vector<Float>& blc, Vector<Float>& trc)
     264             : 
     265             : {
     266           0 :   Int directionIndex=coords.findCoordinate(Coordinate::DIRECTION);
     267           0 :   AlwaysAssert(directionIndex>=0, AipsError);
     268             :   DirectionCoordinate
     269           0 :     directionCoord=coords.directionCoordinate(directionIndex);
     270           0 :   Vector<String> units(2); units = "deg";                       
     271           0 :   directionCoord.setWorldAxisUnits(units);
     272             : 
     273             :   // convert to the EPOCH of these coords
     274           0 :   MDirection::Types t2 = (MDirection::Types) (pointDir.getRef().getType());
     275           0 :   MDirection pointDirE;
     276           0 :   if (t2 != directionCoord.directionType()) {
     277           0 :     MDirection::Convert converter;
     278           0 :     ObsInfo oi=coords.obsInfo();
     279           0 :     converter.setOut(MDirection::Ref(directionCoord.directionType(), 
     280           0 :                                      MeasFrame(oi.obsDate(), oi.telescopePosition())));
     281           0 :     pointDirE = converter(pointDir);
     282           0 :   } else {
     283           0 :     pointDirE = pointDir;
     284             :   }
     285             : 
     286             :   Double freq;
     287             :   {
     288           0 :     Int spectralIndex=coords.findCoordinate(Coordinate::SPECTRAL);
     289           0 :     AlwaysAssert(spectralIndex>=0, AipsError);
     290             :     SpectralCoordinate
     291           0 :       spectralCoord=coords.spectralCoordinate(spectralIndex);
     292             :     
     293           0 :     units.resize(1);
     294           0 :     units = "Hz";
     295           0 :     spectralCoord.setWorldAxisUnits(units);
     296             : 
     297           0 :     Vector<Double> spectralWorld(1);
     298           0 :     Vector<Double> spectralPixel(1);
     299           0 :     spectralPixel(0) = iChan;
     300           0 :     spectralCoord.toWorld(spectralWorld, spectralPixel);  
     301           0 :     freq  = spectralWorld(0);
     302           0 :   }
     303             : 
     304           0 :   Vector<Double> edgeWorld(2);
     305           0 :   Vector<Double> edge1Pixel(2);
     306           0 :   Vector<Double> edge2Pixel(2);
     307             : 
     308             : 
     309             :   // maximumRadius_p: maximum radius at 1 GHz frequency
     310           0 :   Double delta = maximumRadius_p.getValue("rad") *  1.0e+9 / freq;
     311             :   {
     312           0 :     MDirection edgeDir( pointDirE );
     313           0 :     edgeDir.shift( delta, 0.0, true);
     314           0 :     edgeWorld(0) = edgeDir.getAngle().getValue("deg")(0);
     315           0 :     edgeWorld(1) = edgeDir.getAngle().getValue("deg")(1);
     316           0 :     directionCoord.toPixel(edge1Pixel, edgeWorld);
     317           0 :   }
     318             :   {
     319           0 :     MDirection edgeDir( pointDirE );
     320           0 :     edgeDir.shift( -delta, 0.0, true);
     321           0 :     edgeWorld(0) = edgeDir.getAngle().getValue("deg")(0);
     322           0 :     edgeWorld(1) = edgeDir.getAngle().getValue("deg")(1);
     323           0 :     directionCoord.toPixel(edge2Pixel, edgeWorld);
     324           0 :   }
     325           0 :   blc(0) = min( edge1Pixel(0), edge2Pixel(0) );
     326           0 :   trc(0) = max( edge1Pixel(0), edge2Pixel(0) );
     327           0 :   if (fPad > 0.1) {
     328           0 :     Float pad = (trc(0) - blc(0)) * (fPad - 1.0)/2;
     329           0 :     blc(0) = blc(0) - pad;
     330           0 :     trc(0) = trc(0) + pad;
     331             :   }
     332             :   {
     333           0 :     MDirection edgeDir( pointDirE );
     334           0 :     edgeDir.shift( 0.0, delta, true);
     335           0 :     edgeWorld(0) = edgeDir.getAngle().getValue("deg")(0);
     336           0 :     edgeWorld(1) = edgeDir.getAngle().getValue("deg")(1);
     337           0 :     directionCoord.toPixel(edge1Pixel, edgeWorld);
     338           0 :   }
     339             :   {
     340           0 :     MDirection edgeDir( pointDirE );
     341           0 :     edgeDir.shift( 0.0, -delta, true);
     342           0 :     edgeWorld(0) = edgeDir.getAngle().getValue("deg")(0);
     343           0 :     edgeWorld(1) = edgeDir.getAngle().getValue("deg")(1);
     344           0 :     directionCoord.toPixel(edge2Pixel, edgeWorld);
     345           0 :   }
     346           0 :   blc(1) = min( edge1Pixel(1), edge2Pixel(1) );
     347           0 :   trc(1) = max( edge1Pixel(1), edge2Pixel(1) );
     348           0 :   if (fPad > 0.1) {
     349           0 :     Float pad = (trc(1) - blc(1)) * (fPad - 1.0)/2;
     350           0 :     blc(1) = blc(1) - pad;
     351           0 :     trc(1) = trc(1) + pad;
     352             :   }
     353           0 : };
     354             : 
     355             : 
     356             : 
     357             : 
     358           0 : void PBMath1D::symmetrizeSquintedBeam()
     359             : {
     360             :   // eventually we need to create the 2D squinted RR and LL
     361             :   // beams and average them.  For now, we just return the
     362             :   // unsquinted beams
     363             : 
     364           0 :   if (vp_p.nelements() == 0) {
     365           0 :     fillPBArray();
     366             :   }
     367           0 :   esvp_p = vp_p; 
     368           0 : };
     369             : 
     370             : ImageInterface<Complex>&  
     371          48 : PBMath1D::apply(const ImageInterface<Complex>& in,
     372             :                 ImageInterface<Complex>& out,
     373             :                 const MDirection& pointDir,
     374             :                 const Quantity parAngle,       
     375             :                 const BeamSquint::SquintType doSquint,
     376             :                 Bool inverse,
     377             :                 Bool conjugate,
     378             :                 Int iPower,  
     379             :                 Float cutoff,
     380             :                 Bool forward)
     381             : {
     382          96 :   LogIO os(LogOrigin("PBMath1D", "apply"));
     383             :   // Check that in and out are comparable:
     384          48 :   if (in.shape() != out.shape()) {
     385           0 :     throw(AipsError("PBMath1D::apply(ImageInterface...) - in and out images have different shapes"));    
     386             :   } 
     387          48 :   CoordinateSystem coords=in.coordinates();
     388          48 :   if (!coords.near(out.coordinates()) ) {
     389           0 :     throw(AipsError("PBMath1D::apply(ImageInterface...) - in and out images have different coordinates"));    
     390             :   }
     391             : 
     392          48 :   Int directionIndex=coords.findCoordinate(Coordinate::DIRECTION);
     393          48 :   AlwaysAssert(directionIndex>=0, AipsError);
     394             :   DirectionCoordinate
     395          48 :     directionCoord=coords.directionCoordinate(directionIndex);
     396          48 :   Vector<String> units(2); units = "deg";                       
     397          48 :     directionCoord.setWorldAxisUnits(units);
     398             : 
     399             :   // convert to the EPOCH of these coords
     400          48 :   MDirection::Types t2 = (MDirection::Types) (pointDir.getRef().getType());
     401          48 :   MDirection pointDirE;
     402             : 
     403             : 
     404          48 :   if (t2 != directionCoord.directionType()) {
     405           0 :     MDirection::Convert converter;
     406           0 :     ObsInfo oi=coords.obsInfo();
     407           0 :     converter.setOut(MDirection::Ref(directionCoord.directionType(), 
     408           0 :                                      MeasFrame(oi.obsDate(), oi.telescopePosition())));
     409           0 :     pointDirE = converter(pointDir);
     410           0 :   } else {
     411          48 :     pointDirE = pointDir;
     412             :   }
     413             : 
     414          48 :   Int stokesIndex=coords.findCoordinate(Coordinate::STOKES);
     415          48 :   AlwaysAssert(stokesIndex>=0, AipsError);
     416             :   StokesCoordinate
     417          48 :     stokesCoord=coords.stokesCoordinate(stokesIndex);
     418             :  
     419          48 :   Int spectralIndex=coords.findCoordinate(Coordinate::SPECTRAL);
     420          48 :   AlwaysAssert(spectralIndex>=0, AipsError);
     421             :   SpectralCoordinate
     422          48 :     spectralCoord=coords.spectralCoordinate(spectralIndex);
     423             :  
     424          48 :   units.resize(1);
     425          48 :   units = "Hz";
     426          48 :   spectralCoord.setWorldAxisUnits(units);
     427             :  
     428          48 :   Int nchan=in.shape()(3);
     429             :     
     430          48 :   Vector<Double> pointingCenterWorld(2);
     431          48 :   Vector<Double> pointingCenterPixel(2);
     432          48 :   Vector<Double> directionPixel(2);
     433             : 
     434          48 :   pointingCenterWorld(0) = pointDirE.getAngle().getValue("deg")(0);
     435          48 :   pointingCenterWorld(1) = pointDirE.getAngle().getValue("deg")(1);
     436          48 :   directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     437          48 :   MDirection newpointDirE;
     438          48 :   Vector<Double> nonSquintedPointingPixel = pointingCenterPixel.copy();
     439             : 
     440          48 :   os << "pointingCenterWorld " << pointingCenterWorld << LogIO::DEBUGGING;
     441          48 :   os << "pointingCenterPixel " << pointingCenterPixel << LogIO::DEBUGGING;
     442             :   
     443             :   // Fill in a cache of the frequencies & squints
     444          48 :   Vector<Double> spectralWorld(1);
     445          48 :   Vector<Double> spectralPixel(1);
     446          48 :   Matrix<Double> xSquintPixCache(2, nchan);
     447          48 :   Matrix<Double> ySquintPixCache(2, nchan);
     448          48 :   Vector<Double> spectralCache(nchan);
     449             : 
     450             :   {
     451          96 :     for(Int chan=0;chan<nchan;chan++) {
     452          48 :       spectralPixel(0)=chan;
     453          48 :       if(!spectralCoord.toWorld(spectralWorld, spectralPixel)) {
     454           0 :         os  << "Cannot find frequency for this plane" << LogIO::EXCEPTION;
     455             :       }
     456          48 :       spectralCache(chan)=spectralWorld(0);
     457             : 
     458             :       
     459          48 :       if (doSquint == BeamSquint::RR || doSquint == BeamSquint::GOFIGURE) {
     460          40 :         squint_p.getPointingDirection (pointDirE,
     461             :                                        parAngle, 
     462          80 :                                        Quantity(spectralWorld(0),"Hz"),
     463             :                                        BeamSquint::RR, newpointDirE);
     464          40 :         pointingCenterWorld(0) = newpointDirE.getAngle().getValue("deg")(0);
     465          40 :         pointingCenterWorld(1) = newpointDirE.getAngle().getValue("deg")(1);
     466          40 :         directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     467          40 :         xSquintPixCache(0, chan) = pointingCenterPixel(0);
     468          40 :         ySquintPixCache(0, chan) = pointingCenterPixel(1);
     469             :       } else {
     470           8 :         xSquintPixCache(0, chan) =  nonSquintedPointingPixel(0);
     471           8 :         ySquintPixCache(0, chan) =  nonSquintedPointingPixel(1);
     472             :       }
     473          48 :       if (doSquint == BeamSquint::LL || doSquint == BeamSquint::GOFIGURE) {
     474          40 :         squint_p.getPointingDirection (pointDirE,
     475             :                                        parAngle, 
     476          80 :                                        Quantity(spectralWorld(0),"Hz"),
     477             :                                        BeamSquint::LL, newpointDirE);
     478          40 :         pointingCenterWorld(0) = newpointDirE.getAngle().getValue("deg")(0);
     479          40 :         pointingCenterWorld(1) = newpointDirE.getAngle().getValue("deg")(1);
     480          40 :         directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     481          40 :         xSquintPixCache(1, chan) = pointingCenterPixel(0);
     482          40 :         ySquintPixCache(1, chan) = pointingCenterPixel(1);
     483             :       } else {
     484           8 :         xSquintPixCache(1, chan) =  nonSquintedPointingPixel(0);
     485           8 :         ySquintPixCache(1, chan) =  nonSquintedPointingPixel(1);
     486             :       }
     487             :     }
     488             :   }
     489             : 
     490             :   /*
     491             :   cout << "pointingCenterPixel x,y = " << nonSquintedPointingPixel << endl;
     492             :   cout << "squinted pointingCenterPixel x,y RR = " << xSquintPixCache(0, 0) << ", " 
     493             :        << ySquintPixCache(0, 0) << endl;
     494             :   cout << "squinted pointingCenterPixel x,y LL = " << xSquintPixCache(1, 0) << ", " 
     495             :        << ySquintPixCache(1, 0) << endl;
     496             :   */
     497             : 
     498             :   // Iterate through in minimum IO/Memory chunks
     499             :   //IPosition ncs = in.niceCursorShape();
     500          48 :   IPosition ncs=in.shape();
     501          48 :   ncs(2) = 1; ncs(3) = 1;
     502          96 :   RO_LatticeIterator<Complex> li(in, LatticeStepper(in.shape(), ncs, IPosition(4,0,1,2,3) )  );
     503          96 :   LatticeIterator<Complex> oli(out, LatticeStepper(in.shape(), ncs, IPosition(4,0,1,2,3)) );
     504             : 
     505             :   // taper no longer appears to be used
     506             :   //Complex taper;
     507             :   //Float r2=0.0;
     508             :   //Float r=0.0;
     509             : 
     510          48 :   Vector<Double> increment = directionCoord.increment();
     511          48 :   Int rrplane = -1;
     512          48 :   Int llplane = -1;
     513          48 :   stokesCoord.toPixel( rrplane, Stokes::RR );
     514          48 :   stokesCoord.toPixel( llplane, Stokes::LL );
     515             : 
     516             :   /*
     517             :   cout << "stokes types in image = " << stokesCoord.stokes() << endl;
     518             :   cout << "rr plane = " << rrplane << "   ll plane = " << llplane << endl;
     519             : 
     520             :   */
     521             :   Double xPixel;  Double yPixel;
     522             : 
     523          48 :   Int laststokes = -1;
     524          48 :   Int lastChan = -1;
     525             :   Int ichan;
     526             :   Int istokes;
     527             :   Int ix0, iy0;
     528             :   //Int indx;
     529          96 :   for(li.reset(),oli.reset();!li.atEnd();li++,oli++) {
     530             : 
     531          48 :     IPosition itsShape(li.matrixCursor().shape());
     532          48 :     IPosition loc(li.position());
     533             : 
     534          48 :     ichan = loc(3);
     535          48 :     istokes = loc(2);
     536          48 :     iy0 = loc(1);
     537          48 :     ix0 = loc(0);
     538             : 
     539             :     // determine the pointing: RR, LL, or Center? We make a slight mistake
     540             :     // here since we ignore the difference between the RR beam and the
     541             :     // RL beam, say. The latter is slightly smaller because of the
     542             :     // squint. Hence this code should be deprecated in favor of the
     543             :     // correct 2D version (when mosaicing in polarization)
     544          48 :     if ((doSquint == BeamSquint::RR) ||
     545          40 :         ((doSquint == BeamSquint::GOFIGURE) && (istokes == rrplane)) ) {
     546           0 :       xPixel = xSquintPixCache(0, ichan);
     547           0 :       yPixel = ySquintPixCache(0, ichan);
     548          48 :     } else if ((doSquint == BeamSquint::LL) ||
     549          40 :                ((doSquint == BeamSquint::GOFIGURE) && (istokes == llplane)) ) {
     550           0 :       xPixel = xSquintPixCache(1, ichan);
     551           0 :       yPixel = ySquintPixCache(1, ichan);
     552             :     } else {
     553          48 :       xPixel = nonSquintedPointingPixel(0);
     554          48 :       yPixel = nonSquintedPointingPixel(1);
     555             :     }
     556             : 
     557          48 :     if (istokes != laststokes) {
     558             :       //cerr << "Stokes = " << istokes << " pix = " << xPixel << ", " << yPixel << endl;
     559          48 :       laststokes = istokes;
     560             :     }
     561             : 
     562          48 :     Double factor = 60.0 * spectralCache(ichan)/1.0e+9 ;  // arcminutes * GHz
     563          48 :     Double rmax2 = square( maximumRadius_p.getValue("'") / factor );
     564          48 :     if (wideFit_p) {
     565             :       // fill vp with interpolated values for current frequency
     566           0 :       if (ichan!=lastChan) {
     567           0 :         nearestVPArray(spectralCache(ichan));
     568           0 :         lastChan=ichan;
     569             :       }
     570             :     }
     571             :                        
     572          48 :     Vector<Float> rx2(itsShape(0));
     573          48 :     Vector<Float> ry2(itsShape(1));
     574      324568 :     for(Int ix=0;ix<itsShape(0);ix++) {
     575      324520 :       rx2(ix) =  square( increment(0)*((Double)(ix+ix0) - xPixel) );
     576             :     }
     577       74984 :     for(Int iy=0;iy<itsShape(1);iy++) {
     578       74936 :       ry2(iy) =  square( increment(1)*((Double)(iy+iy0) - yPixel) );
     579             :     }
     580             :    
     581          48 :     const Matrix<Complex>& inmat = li.matrixCursor();
     582          48 :     Matrix<Complex>& outmat=oli.rwMatrixCursor();
     583             : 
     584             :     Bool incopy, outcopy, del;
     585          48 :     const Complex * inpoint = inmat.getStorage(incopy);
     586          48 :     Complex *outpoint =outmat.getStorage(outcopy);
     587          48 :     Float * rx2point = rx2.getStorage(del);
     588          48 :     Float * ry2point= ry2.getStorage(del);
     589          48 :     Complex* vppoint=vp_p.getStorage(del);
     590          48 :     Int nx=itsShape(0);
     591          48 :     Int ny=itsShape(1);
     592          48 :     Double inverseIncrementRadius=inverseIncrementRadius_p;
     593          48 : #pragma omp parallel default(none) firstprivate(inpoint, outpoint, rx2point, ry2point, vppoint, iPower, conjugate, inverse, forward, nx, ny, rmax2, factor, inverseIncrementRadius, cutoff)
     594             :     {
     595             : #pragma omp for   
     596             :     for(Int iy=0;iy<ny;iy++) {
     597             :       Float ry2val=ry2point[iy];
     598             :       applyXLine(inpoint, outpoint , rx2point , vppoint , ry2val, iPower, conjugate, inverse, forward, nx, iy, rmax2, 
     599             :                  factor, inverseIncrementRadius, cutoff);
     600             :       /*for(Int ix=0;ix<itsShape(0);ix++) {
     601             : 
     602             :         r2 =  rx2(ix) +  ry2(iy);
     603             :         
     604             :         if (r2 > rmax2) {
     605             :           oli.rwMatrixCursor()(ix, iy) = 0.0;
     606             :         } else {
     607             :           r = sqrt(r2) * factor;
     608             :           indx = Int(r*inverseIncrementRadius_p);
     609             :           if (norm(vp_p(indx)) > 0.0) {
     610             :             if(iPower==2) {
     611             :               taper = vp_p(indx) * conj(vp_p(indx));
     612             :             }
     613             :             else {
     614             :               taper = vp_p(indx);
     615             :             }
     616             :           } else {
     617             :             taper = 0.0;
     618             :           }
     619             :           if (conjugate) {
     620             :             taper =  conj(taper);
     621             :           }
     622             :           // Differentiate between forward (Sky->UV) and
     623             :           // inverse (UV->Sky) - these need different
     624             :           // applications of the PB
     625             :           if(!forward) {
     626             :             taper =  conj(taper);
     627             :           }
     628             :           if (inverse) {
     629             :             if (abs(taper) < cutoff ) {
     630             :               oli.rwMatrixCursor()(ix, iy) = 0.0;
     631             :             } else {
     632             :               oli.rwMatrixCursor()(ix, iy) = li.matrixCursor()(ix, iy) / taper ;
     633             :             }
     634             :           } else {  // not inverse!
     635             :             oli.rwMatrixCursor()(ix, iy) = li.matrixCursor()(ix, iy) * taper;
     636             :           }
     637             :         }
     638             :       }
     639             :       */
     640             :     }
     641             :     } //end pragma
     642          48 :     outmat.putStorage(outpoint, outcopy);
     643          48 :     inmat.freeStorage(inpoint, incopy);
     644          48 :   }
     645             : 
     646          48 :   return out;
     647             : 
     648          48 : };
     649             : 
     650       74936 :   void PBMath1D::applyXLine(const Complex*& in, Complex*& out, Float*& rx2, Complex*& vp, const Float ry2, const Int ipower, const Bool conjugate, const Bool inverse, const Bool forward, const Int nx, const Int iy, const Double rmax2, const Double factor, const Double inverseIncrementRadius, const Float cutoff)
     651             : { 
     652             :   Float r;
     653             :   Int indx;
     654       74936 :   Complex taper;
     655   140899296 :   for(Int ix=0;ix<nx;ix++) {
     656             :     
     657   140824360 :     Float r2 =  rx2[ix] +  ry2;
     658             :         
     659   140824360 :     if (r2 > rmax2){
     660   105274055 :       out[ix+iy*nx] = 0.0;
     661             :     } 
     662             :     else {
     663    35550305 :       r = sqrt(r2) * factor;
     664    35550305 :       indx = Int(r*inverseIncrementRadius);
     665    35550305 :       if (norm(vp[indx]) > 0.0) {
     666    35550305 :         if(ipower==2) {
     667    35550305 :           taper = vp[indx] * conj(vp[indx]);
     668             :         }
     669             :         else {
     670           0 :           taper = vp[indx];
     671             :         }
     672             :       } else {
     673           0 :         taper = 0.0;
     674             :       }
     675    35550305 :       if (conjugate) {
     676           0 :         taper =  conj(taper);
     677             :       }
     678             :       // Differentiate between forward (Sky->UV) and
     679             :       // inverse (UV->Sky) - these need different
     680             :       // applications of the PB
     681    35550305 :       if(!forward) {
     682           0 :         taper =  conj(taper);
     683             :       }
     684    35550305 :       if (inverse) {
     685           0 :         if (abs(taper) < cutoff ) {
     686           0 :           out[ix+iy*nx] = 0.0;
     687             :         } else {
     688           0 :           out[ix+iy*nx]  = (in[ix+iy*nx]) / taper ;
     689             :         }
     690             :       } else {  // not inverse!
     691    35550305 :         out[ix+iy*nx]  = (in[ix+iy*nx]) * taper ;
     692             :       }
     693             :     }
     694             :   }
     695       74936 : };
     696             : 
     697             : ImageInterface<Float>& 
     698           0 : PBMath1D::apply(const ImageInterface<Float>& in,
     699             :                 ImageInterface<Float>& out,
     700             :                 const MDirection& pointDir,
     701             :                 const Quantity parAngle,
     702             :                 const BeamSquint::SquintType doSquint,
     703             :                 Float /*cutoff*/, const Int ipower)
     704             : {
     705           0 :   LogIO os(LogOrigin("PBMath1D", "apply"));
     706             :  
     707             :   //  cout << "PBMath1D::apply: image shape: " << in.shape() << endl;
     708             :   // Check that in and out are comparable:
     709           0 :   if (in.shape() != out.shape()) {
     710           0 :     throw(AipsError("PBMath1D::apply(ImageInterface...) - in and out images have different shapes"));
     711             :     
     712             :   } 
     713           0 :   CoordinateSystem coords=in.coordinates();
     714           0 :   if (!coords.near(out.coordinates())) {
     715           0 :     throw(AipsError("PBMath1D::apply(ImageInterface...) - in and out images have different coordinates"));
     716             :   }
     717             : 
     718           0 :   Int directionIndex=coords.findCoordinate(Coordinate::DIRECTION);
     719           0 :   AlwaysAssert(directionIndex>=0, AipsError);
     720             :   DirectionCoordinate
     721           0 :     directionCoord=coords.directionCoordinate(directionIndex);
     722           0 :   Vector<String> units(2); units = "deg";                       
     723           0 :     directionCoord.setWorldAxisUnits(units);
     724             : 
     725             :   // convert to the EPOCH of these coords
     726           0 :   MDirection::Types t2 = (MDirection::Types) (pointDir.getRef().getType());
     727           0 :   MDirection pointDirE(pointDir);
     728             : 
     729           0 :   if (t2 != directionCoord.directionType()) {
     730           0 :     MDirection::Convert converter;
     731           0 :     ObsInfo oi=coords.obsInfo();
     732           0 :     converter.setOut(MDirection::Ref(directionCoord.directionType(), 
     733           0 :                                      MeasFrame(oi.obsDate(), oi.telescopePosition())));
     734           0 :     pointDirE = converter(pointDir);
     735           0 :   } else {
     736           0 :     pointDirE = pointDir;
     737             :   }
     738           0 :   Int stokesIndex=coords.findCoordinate(Coordinate::STOKES);
     739           0 :   AlwaysAssert(stokesIndex>=0, AipsError);
     740             :   StokesCoordinate
     741           0 :     stokesCoord=coords.stokesCoordinate(stokesIndex);
     742             :  
     743           0 :   Int spectralIndex=coords.findCoordinate(Coordinate::SPECTRAL);
     744           0 :   AlwaysAssert(spectralIndex>=0, AipsError);
     745             :   SpectralCoordinate
     746           0 :     spectralCoord=coords.spectralCoordinate(spectralIndex);
     747             :  
     748           0 :   units.resize(1);
     749           0 :   units = "Hz";
     750           0 :   spectralCoord.setWorldAxisUnits(units);
     751             :  
     752           0 :   Int nchan=in.shape()(3);
     753             :     
     754           0 :   Vector<Double> pointingCenterWorld(2);
     755           0 :   Vector<Double> pointingCenterPixel(2);
     756           0 :   Vector<Double> directionPixel(2);
     757             : 
     758           0 :   pointingCenterWorld(0) = pointDirE.getAngle().getValue("deg")(0);
     759           0 :   pointingCenterWorld(1) = pointDirE.getAngle().getValue("deg")(1);
     760           0 :   directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     761           0 :   MDirection newpointDirE;
     762           0 :   Vector<Double> nonSquintedPointingPixel = pointingCenterPixel.copy();
     763             : 
     764           0 :   os << "pointingCenterWorld " << pointingCenterWorld << LogIO::DEBUGGING;
     765           0 :   os << "pointingCenterPixel " << pointingCenterPixel << LogIO::DEBUGGING;
     766             : 
     767             :   // Fill in a cache of the frequencies & squints
     768           0 :   Vector<Double> spectralWorld(1);
     769           0 :   Vector<Double> spectralPixel(1);
     770           0 :   Matrix<Double> xSquintPixCache(2, nchan);  // kludge: prevent errors when nchan = 1
     771           0 :   Matrix<Double> ySquintPixCache(2, nchan);
     772           0 :   Vector<Double> spectralCache(nchan);
     773             : 
     774             :   {
     775           0 :     for(Int chan=0;chan<nchan;chan++) {
     776           0 :       spectralPixel(0)=chan;
     777           0 :       if(!spectralCoord.toWorld(spectralWorld, spectralPixel)) {
     778           0 :         os  << "Cannot find frequency for this plane" << LogIO::EXCEPTION;
     779             :       }
     780           0 :       spectralCache(chan)=spectralWorld(0);
     781             : 
     782             :       
     783           0 :       if (doSquint == BeamSquint::RR || doSquint == BeamSquint::GOFIGURE) {
     784           0 :         squint_p.getPointingDirection (pointDirE,
     785             :                                        parAngle, 
     786           0 :                                        Quantity(spectralWorld(0),"Hz"),
     787             :                                        BeamSquint::RR, newpointDirE);
     788           0 :         pointingCenterWorld(0) = newpointDirE.getAngle().getValue("deg")(0);
     789           0 :         pointingCenterWorld(1) = newpointDirE.getAngle().getValue("deg")(1);
     790           0 :         directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     791           0 :         xSquintPixCache(0, chan) = pointingCenterPixel(0);
     792           0 :         ySquintPixCache(0, chan) = pointingCenterPixel(1);
     793             :       } else {
     794           0 :         xSquintPixCache(0, chan) =  nonSquintedPointingPixel(0);
     795           0 :         ySquintPixCache(0, chan) =  nonSquintedPointingPixel(1);
     796             :       }
     797           0 :       if (doSquint == BeamSquint::LL || doSquint == BeamSquint::GOFIGURE) {
     798           0 :         squint_p.getPointingDirection (pointDirE,
     799             :                                        parAngle, 
     800           0 :                                        Quantity(spectralWorld(0),"Hz"),
     801             :                                        BeamSquint::LL, newpointDirE);
     802           0 :         pointingCenterWorld(0) = newpointDirE.getAngle().getValue("deg")(0);
     803           0 :         pointingCenterWorld(1) = newpointDirE.getAngle().getValue("deg")(1);
     804           0 :         directionCoord.toPixel(pointingCenterPixel, pointingCenterWorld);
     805           0 :         xSquintPixCache(1, chan) = pointingCenterPixel(0);
     806           0 :         ySquintPixCache(1, chan) = pointingCenterPixel(1);
     807             :       } else {
     808           0 :         xSquintPixCache(1, chan) =  nonSquintedPointingPixel(0);
     809           0 :         ySquintPixCache(1, chan) =  nonSquintedPointingPixel(1);
     810             :       }
     811             :     }
     812             :   }
     813             : 
     814             : 
     815             :   // Iterate through in minimum IO/Memory chunks
     816           0 :   IPosition ncs = in.niceCursorShape();
     817             :   // IPosition ncs=in.shape();
     818           0 :   ncs(2) = 1; ncs(3) = 1;
     819           0 :   ncs(2) = 1; ncs(3) = 1;
     820           0 :   RO_LatticeIterator<Float> li(in, LatticeStepper(in.shape(), ncs, IPosition(4,0,1,2,3) )  );
     821           0 :   LatticeIterator<Float> oli(out, LatticeStepper(in.shape(), ncs, IPosition(4,0,1,2,3)) );
     822             : 
     823             :   //Vector<Float> taper(vp_p.nelements());
     824           0 :   Float taper=0.0;
     825           0 :   Float r2=0.0;
     826           0 :   Float r=0.0;
     827             : 
     828           0 :   Vector<Double> increment = directionCoord.increment();
     829           0 :   Int rrplane = -1;
     830           0 :   Int llplane = -1;
     831           0 :   stokesCoord.toPixel( rrplane, Stokes::RR );
     832           0 :   stokesCoord.toPixel( llplane, Stokes::LL );
     833             : 
     834             :   Double xPixel;  Double yPixel;
     835             : 
     836           0 :   Int laststokes = -1;
     837           0 :   Int lastChan   = -1;
     838             :   Int ichan;
     839             :   Int istokes;
     840             :   Int ix0, iy0;
     841             :   Int indx;
     842             : 
     843           0 :   for(li.reset(),oli.reset();!li.atEnd();li++,oli++) {
     844             : 
     845           0 :     IPosition itsShape(li.matrixCursor().shape());
     846           0 :     IPosition loc(li.position());
     847             : 
     848           0 :     ichan = loc(3);
     849           0 :     istokes = loc(2);
     850           0 :     iy0 = loc(1);
     851           0 :     ix0 = loc(0);
     852             : 
     853             :     // determine the pointing: RR, LL, or Center?
     854           0 :     if ((doSquint == BeamSquint::RR) ||
     855           0 :         ((doSquint == BeamSquint::GOFIGURE) && (istokes == rrplane)) ) {
     856           0 :       xPixel = xSquintPixCache(0, ichan);
     857           0 :       yPixel = ySquintPixCache(0, ichan);
     858           0 :     } else if ((doSquint == BeamSquint::LL) ||
     859           0 :                ((doSquint == BeamSquint::GOFIGURE) && (istokes == llplane ))) {
     860           0 :       xPixel = xSquintPixCache(1, ichan);
     861           0 :       yPixel = ySquintPixCache(1, ichan);
     862             :     } else {
     863           0 :       xPixel = nonSquintedPointingPixel(0);
     864           0 :       yPixel = nonSquintedPointingPixel(1);
     865             :     }
     866             :   
     867           0 :     if (istokes != laststokes) {
     868             :       //      cout << "Stokes = " << istokes << " pix = " << xPixel << ", " << yPixel << endl;
     869           0 :       laststokes = istokes;
     870             :     }
     871             : 
     872           0 :     Double factor = 60.0 * spectralCache(ichan)/1.0e+9 ;  // arcminutes * GHz
     873           0 :     Double rmax2 = square( maximumRadius_p.getValue("'") / factor );
     874           0 :     if (wideFit_p) {
     875             :       // fill vp with interpolated values for current frequency
     876           0 :       if (ichan!=lastChan) {
     877           0 :         nearestVPArray(spectralCache(ichan));
     878           0 :         lastChan = ichan;
     879             :       }
     880             :     }
     881             :     
     882             :     //taper.set(0.0);
     883             :     /*for (uInt inda=0; inda < vp_p.nelements(); ++inda){
     884             :       if (norm(vp_p(inda)) > 0.0) {
     885             :         taper[inda] = real(vp_p(inda)) * real(vp_p(inda)) + imag(vp_p(inda))*imag(vp_p(inda));
     886             :         if(ipower==4)
     887             :           taper[inda] *= taper[inda];
     888             :       } 
     889             : 
     890             :     } 
     891             :     */
     892             : 
     893           0 :     Vector<Float> rx2(itsShape(0));
     894           0 :     Vector<Float> ry2(itsShape(1));
     895           0 :     for(Int ix=0;ix<itsShape(0);ix++) {
     896           0 :       rx2(ix) =  square( increment(0)*((Double)(ix+ix0) - xPixel) );
     897             :     }
     898           0 :     for(Int iy=0;iy<itsShape(1);iy++) {
     899           0 :       ry2(iy) =  square( increment(1)*((Double)(iy+iy0) - yPixel) );
     900             :     }
     901             : 
     902           0 :     for(Int iy=0;iy<itsShape(1);iy++) {
     903           0 :       for(Int ix=0;ix<itsShape(0);ix++) {
     904             : 
     905           0 :         r2 =  rx2(ix) +  ry2(iy);
     906           0 :         if (r2 > rmax2) {
     907           0 :           oli.rwMatrixCursor()(ix, iy) = 0.0;
     908             :         } else {
     909           0 :           r = sqrt(r2) * factor;
     910           0 :           indx = Int(r*inverseIncrementRadius_p);
     911           0 :           if (norm(vp_p(indx)) > 0.0) {
     912           0 :             taper = real(vp_p(indx)) * real(vp_p(indx))+ imag(vp_p(indx)) * imag(vp_p(indx));
     913           0 :             if(ipower==4)
     914           0 :               taper *= taper;
     915             :           }
     916             :           //else {
     917             :           //  taper = 0.0;
     918             :           //}
     919           0 :           oli.rwMatrixCursor()(ix, iy) = li.matrixCursor()(ix,iy) * taper;
     920             :         }
     921             :       }
     922             :     }
     923           0 :   }
     924           0 :   return out;
     925             : 
     926           0 : };
     927             : 
     928             : // Behavior:  doSquint == RR or LL don't make sense here
     929             : //
     930             : //
     931             :  
     932             : SkyComponent& 
     933        2491 : PBMath1D::apply(SkyComponent& in,
     934             :                 SkyComponent& out,
     935             :                 const MDirection& pointDir,
     936             :                 const Quantity frequency,
     937             :                 const Quantity parAngle,          
     938             :                 const BeamSquint::SquintType doSquint,
     939             :                 Bool inverse,
     940             :                 Bool conjugate,
     941             :                 Int iPower,
     942             :                 Float cutoff,
     943             :                 Bool /*forward*/)
     944             : {
     945             :   // if ( doSquint == NONE ) we can deal with any polarisation representation
     946             :   // if ( doSquint == GOFIGURE) an exception is thrown if polarisation is not CIRCULAR
     947             :   // if ( doSquint == RR || doSquint == LL ) an exception is thrown,
     948             :   //           as it is not valid to apply the RR or LL squint to ALL polarisations
     949             : 
     950             :   // Also: we can do nothing with spectral index models
     951             :   
     952             : 
     953             :   // convert to the EPOCH of these coords
     954        2491 :   MDirection::Types t1 = (MDirection::Types) (in.shape().refDirection().getRef().getType());
     955        2491 :   MDirection::Types t2 = (MDirection::Types) (pointDir.getRef().getType());
     956             : 
     957        2491 :   MDirection pointDirE;
     958        2491 :   if ( t1 != t2) {
     959           0 :     MDirection::Convert converter;
     960           0 :     converter.setOut( t1 );
     961           0 :     pointDirE = converter(pointDir);
     962           0 :   } else {
     963        2491 :     pointDirE = pointDir;
     964             :   }
     965             : 
     966        2491 :   if (doSquint == BeamSquint::RR || doSquint == BeamSquint::LL) {
     967           0 :     throw(AipsError("PBMath1D::apply(SkyComponent...) - cannot force a SkyComponent to have Squint RR or LL"));
     968             :   }
     969        2491 :   if (doSquint == BeamSquint::GOFIGURE) {
     970        2491 :     if (in.flux().pol() != ComponentType::CIRCULAR) {
     971         397 :       in.flux().convertPol(ComponentType::CIRCULAR);
     972             :     }
     973             :   }
     974             : 
     975        2491 :   Vector<DComplex> compFluxIn = in.flux().value();
     976        2491 :   Vector<DComplex> compFlux = out.flux().value();
     977        2491 :   compFlux = compFluxIn.copy();
     978             : 
     979             :   // Find the direction of the component
     980        2491 :   MDirection compDir = in.shape().refDirection();
     981             : 
     982             :   // Now taper all polarizations appropriately
     983             :   
     984             :   // Sort out any frequency interpolation
     985             :   //Int ifit=0;
     986             :   //Float lfit=0;
     987             :   //Int nFreq=wFreqs_p.nelements();
     988        2491 :   if (wideFit_p) {
     989           0 :     Double freq = frequency.getValue("Hz");
     990           0 :     nearestVPArray(freq);
     991             :     /* for (ifit=0; ifit<nFreq; ifit++) {
     992             :       if (freq<=wFreqs_p(ifit)) break;
     993             :     }
     994             :     if (ifit>0 && ifit<nFreq) {
     995             :       lfit=(freq-wFreqs_p(ifit-1)) / (wFreqs_p(ifit)-wFreqs_p(ifit-1));
     996             :     }
     997             :     */
     998             :   }
     999             :   
    1000        2491 :   MDirection newpointDirE;
    1001       12455 :   for (Int pol=0;pol<4;pol++) {
    1002        9964 :     Stokes::StokesTypes stokes=Stokes::type(pol+5);
    1003             : 
    1004        9964 :     if (stokes == Stokes::RR &&  doSquint == BeamSquint::GOFIGURE) {
    1005        2491 :       squint_p.getPointingDirection (pointDirE, parAngle, frequency, BeamSquint::RR,
    1006             :                                      newpointDirE );
    1007        7473 :     } else if (stokes == Stokes::LL && doSquint == BeamSquint::GOFIGURE) {
    1008        2491 :       squint_p.getPointingDirection (pointDirE, parAngle, frequency, BeamSquint::LL,
    1009             :                                      newpointDirE );
    1010             :     } else {
    1011        4982 :       newpointDirE = pointDirE;
    1012             :     }
    1013             : 
    1014        9964 :     MVDirection mvd1( compDir.getAngle() );
    1015        9964 :     MVDirection mvd2( newpointDirE.getAngle() );
    1016        9964 :     Quantity sep =  mvd1.separation(mvd2, "'"); 
    1017        9964 :     double r = sep.getValue("'") * frequency.getValue("Hz") / 1.0e+9;  // arcminutes * GHz 
    1018        9964 :     Complex taper;
    1019        9964 :     Int ir = Int(r*inverseIncrementRadius_p);
    1020             :     //vp_p is interpolated wvp_p from above 
    1021        9964 :     Complex vpVal = ir >= Int(vp_p.nelements()) ? Complex(0) : vp_p(ir);
    1022             :     /*if (wideFit_p) {
    1023             :       if (ifit==0) {
    1024             :         vpVal = wbvp_p(ir,0);
    1025             :       } else if (ifit==nFreq) {
    1026             :         vpVal = wbvp_p(ir,nFreq-1);
    1027             :       } else {
    1028             :         vpVal = wbvp_p(ir,ifit-1)*(1-lfit) + wbvp_p(ir,ifit)*lfit;
    1029             :       }
    1030             :     }
    1031             :      */
    1032             :     
    1033        9964 :     if (r > maximumRadius_p.getValue("'")) {
    1034         192 :       compFlux(pol) = 0.0;
    1035             :     } else {
    1036        9772 :       if (norm(vpVal) > 0.0) {
    1037        9772 :         if(iPower>1){
    1038        9772 :           taper=vpVal*conj(vpVal);
    1039        9772 :           if(iPower==4)
    1040           0 :             taper*=taper;
    1041             :         }  
    1042             :         else{
    1043           0 :           taper = vpVal;
    1044             :           //taper = pow( vp_p(Int(r*inverseIncrementRadius_p)), (Float)iPower);
    1045             :         }
    1046             :       } else {
    1047           0 :         taper = 0.0;
    1048             :       }
    1049        9772 :       if (conjugate) {
    1050           0 :         taper =  conj(taper);
    1051             :       }
    1052        9772 :       if (inverse) {
    1053           0 :         if (abs(taper) < cutoff ) {
    1054           0 :           compFlux(pol) = 0.0;
    1055             :         } else {
    1056           0 :           compFlux(pol) /= taper ;
    1057             :         }
    1058             :       } else {  // not inverse!
    1059        9772 :         compFlux(pol) *= taper;
    1060             :       }
    1061             :     }    
    1062        9964 :   }
    1063             : 
    1064             :   // Set the output component fluxes 
    1065        2491 :   out = in.copy();
    1066        2491 :   out.flux().setValue(compFlux);
    1067             : 
    1068        2491 :   return out;
    1069             : 
    1070        2491 : };
    1071             : 
    1072          14 : void PBMath1D::summary(Int nValues)
    1073             : {
    1074          14 :   String  name;
    1075          14 :   namePBClass(name);
    1076          28 :   LogIO os(LogOrigin("PBMath1D", "summary"));
    1077          14 :   os << "Using " << name << " PB Class " <<  LogIO::POST;
    1078          14 :   PBMathInterface::summary(nValues);
    1079             : 
    1080          14 :   if (nValues > 0) {
    1081           0 :     os << "Primary Beam Sampled Data: " <<  LogIO::POST;
    1082           0 :     os << "  r[']      pb[@ 1 GHz] " <<  LogIO::POST;
    1083           0 :     Vector<Float> rr;
    1084           0 :     Vector<Float> pb;
    1085           0 :     viewPB(rr, pb, nValues);
    1086           0 :     for (Int ii=0;ii<nValues;ii++) { 
    1087           0 :       os << rr(ii) << " " << pb(ii) <<  LogIO::POST; 
    1088             :     }
    1089           0 :   }
    1090             :   os << "Max Radius at " <<   refFreq_p.getValue("GHz") << " GHz: " 
    1091          14 :      << maximumRadius_p.getValue("'") << " arcmin " <<  LogIO::POST; 
    1092             : 
    1093          14 : };
    1094             : 
    1095             : 
    1096         453 : Bool PBMath1D::ok()
    1097             : {
    1098         453 :   if (vp_p.nelements() == 0) {
    1099           0 :     return false;
    1100         453 :   } else if (maximumRadius_p.getValue() <= 0.0) {
    1101           0 :     return false;
    1102         453 :   } else if (refFreq_p.getValue() <= 0.0) {
    1103           0 :     return false;
    1104         453 :   } else if (inverseIncrementRadius_p <= 0.0) {
    1105           0 :     return false;
    1106             :   } else {
    1107         453 :     return true;
    1108             :   }
    1109             : };
    1110             : 
    1111             : 
    1112           0 : void PBMath1D::viewPB(Vector<Float>& r, Vector<Float>& pb, Int n_pb, const Double freq)
    1113             : {
    1114           0 :   r.resize(n_pb);
    1115           0 :   pb.resize(n_pb);
    1116           0 :   if(wideFit_p)
    1117           0 :     nearestVPArray(freq);
    1118           0 :   Int nSamples= vp_p.nelements();
    1119           0 :   for (Int i=0; i< n_pb; i++) {
    1120           0 :     pb(i) = norm( vp_p( (Int) ((nSamples-1)* (((Float)i)/(n_pb-1) ) ) ) );
    1121           0 :     r(i) =  maximumRadius_p.getValue("'") *  (((Float)i)/(n_pb-1));
    1122             :   }
    1123             : 
    1124           0 : };
    1125           0 : void PBMath1D::nearestVPArray(Double freq, bool printINFO){
    1126           0 :     LogIO os(LogOrigin("PBMATH1D", "nearestVPArray"));
    1127           0 :     Int ifit=0;
    1128             :   
    1129           0 :   Int nFreq=wFreqs_p.nelements();
    1130           0 :   for (ifit=0; ifit<nFreq; ifit++) {
    1131           0 :     if (freq <=wFreqs_p(ifit)) break;
    1132             :   }
    1133           0 :   if(printINFO)
    1134           0 :         os << LogIO::NORMAL1 << "Using beam model of frequency  " << ((ifit==nFreq) ? wFreqs_p(nFreq-1) : wFreqs_p(ifit)) << " MHz " << LogIO::POST;
    1135           0 :   if (ifit==0) {
    1136           0 :     vp_p = wbvp_p.column(0);
    1137           0 :   } else if (ifit==nFreq) {
    1138           0 :     vp_p = wbvp_p.column(nFreq-1);
    1139             :   } else {
    1140           0 :     Float l = (freq - wFreqs_p(ifit-1))/
    1141           0 :       (wFreqs_p(ifit)-wFreqs_p(ifit-1));
    1142           0 :     vp_p = wbvp_p.column(ifit-1)*(1-l) + wbvp_p.column(ifit)*l;
    1143             :   }
    1144             : 
    1145             : 
    1146           0 : }
    1147             : 
    1148             : } //# NAMESPACE CASA - END
    1149             : 

Generated by: LCOV version 1.16