LCOV - code coverage report
Current view: top level - components/ComponentModels - SkyComponent.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 163 199 81.9 %
Date: 2023-10-25 08:47:59 Functions: 30 34 88.2 %

          Line data    Source code
       1             : //# SkyComponent.cc:  this defines SkyComponent
       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: aips2-request@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: SkyComponent.cc 21292 2012-11-28 14:58:19Z gervandiepen $
      27             : 
      28             : #include <casacore/casa/Quanta/QMath.h>
      29             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      30             : #include <components/ComponentModels/SkyComponent.h>
      31             : #include <components/ComponentModels/ComponentShape.h>
      32             : #include <components/ComponentModels/Flux.h>
      33             : #include <components/ComponentModels/SkyCompRep.h>
      34             : #include <components/ComponentModels/SpectralModel.h>
      35             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      36             : #include <casacore/casa/Arrays/Vector.h>
      37             : #include <casacore/casa/Containers/RecordInterface.h>
      38             : #include <casacore/casa/Exceptions/Error.h>
      39             : #include <iomanip>
      40             : #include <casacore/casa/Logging/LogIO.h>
      41             : #include <casacore/casa/Logging/LogOrigin.h>
      42             : #include <casacore/casa/Quanta/MVTime.h>
      43             : #include <casacore/casa/Utilities/Precision.h>
      44             : 
      45             : #include <casacore/measures/Measures/MDirection.h>
      46             : #include <casacore/measures/Measures/MFrequency.h>
      47             : 
      48             : #include <casacore/casa/Quanta/MVAngle.h>
      49             : #include <casacore/casa/Utilities/Assert.h>
      50             : #include <casacore/casa/BasicSL/String.h>
      51             : 
      52             : #include <iomanip>
      53             : 
      54             : using namespace casacore;
      55             : namespace casa { //# NAMESPACE CASA - BEGIN
      56             : 
      57        9976 : SkyComponent::SkyComponent()
      58        9976 :   :itsCompPtr(new SkyCompRep) 
      59        9976 : {}
      60             : 
      61          24 : SkyComponent::SkyComponent(const ComponentType::Shape& shape)   
      62          24 :   :itsCompPtr(new SkyCompRep(shape))
      63          24 : {}
      64             : 
      65         308 : SkyComponent::SkyComponent(const ComponentType::Shape& shape,
      66         308 :                            const ComponentType::SpectralShape& spectralModel) 
      67         308 :   :itsCompPtr(new SkyCompRep(shape, spectralModel))
      68         308 : {}
      69             : 
      70       11204 : SkyComponent::SkyComponent(const Flux<Double>& flux,
      71             :                            const ComponentShape& shape, 
      72       11204 :                            const SpectralModel& spectrum)
      73       11204 :   :itsCompPtr(new SkyCompRep(flux, shape, spectrum))
      74       11204 : {}
      75             : 
      76        6028 : SkyComponent::SkyComponent(const SkyComponent& other) 
      77             :   :SkyCompBase(other),
      78        6028 :    itsCompPtr (other.itsCompPtr)
      79        6028 : {}
      80             : 
      81       27540 : SkyComponent::~SkyComponent() {}
      82             : 
      83        8720 : SkyComponent& SkyComponent::operator=(const SkyComponent& other) {
      84        8720 :   if (this != &other)
      85        8720 :     itsCompPtr = other.itsCompPtr;
      86        8720 :   return *this;
      87             : }
      88             : 
      89       43388 : Flux<Double>& SkyComponent::flux() {
      90       43388 :   return itsCompPtr->flux();
      91             : }
      92             : 
      93       11083 : const Flux<Double>& SkyComponent::flux() const {
      94       11083 :   return itsCompPtr->flux();
      95             : }
      96             : 
      97       14211 : const ComponentShape& SkyComponent::shape() const {
      98       14211 :   return itsCompPtr->shape();
      99             : }
     100             : 
     101      154842 : ComponentShape& SkyComponent::shape() {
     102      154842 :   return itsCompPtr->shape();
     103             : }
     104             : 
     105        3076 : void SkyComponent::setShape(const ComponentShape& newShape) {
     106        3076 :   itsCompPtr->setShape(newShape);
     107        3076 : }
     108             : 
     109       11476 : const SpectralModel& SkyComponent::spectrum() const {
     110       11476 :   return itsCompPtr->spectrum();
     111             : }
     112             : 
     113        1049 : SpectralModel& SkyComponent::spectrum() {
     114        1049 :   return itsCompPtr->spectrum();
     115             : }
     116             : 
     117         451 : void SkyComponent::setSpectrum(const SpectralModel& newSpectrum) {
     118         451 :   itsCompPtr->setSpectrum(newSpectrum);
     119         451 : }
     120             : 
     121       11813 : String& SkyComponent::label() {
     122       11813 :   return itsCompPtr->label();
     123             : }
     124             : 
     125       11083 : const String& SkyComponent::label() const {
     126       11083 :   return itsCompPtr->label();
     127             : }
     128             : 
     129       11083 : Vector<Double>& SkyComponent::optionalParameters() {
     130       11083 :    return itsCompPtr->optionalParameters();
     131             : }
     132             : 
     133       11083 : const Vector<Double>& SkyComponent::optionalParameters() const {
     134       11083 :    return itsCompPtr->optionalParameters();
     135             : }
     136             : 
     137           0 : Bool SkyComponent::isPhysical() const {
     138           0 :   return itsCompPtr->isPhysical();
     139             : }
     140             : 
     141        2491 : Flux<Double> SkyComponent::sample(const MDirection& direction, 
     142             :                               const MVAngle& pixelLatSize, 
     143             :                               const MVAngle& pixelLongSize, 
     144             :                               const MFrequency& centerFrequency) const {
     145        2491 :   return itsCompPtr->sample(direction, pixelLatSize, pixelLongSize, 
     146        2491 :                             centerFrequency);
     147             : }
     148             : 
     149        4439 : void SkyComponent::sample(Cube<Double>& samples, const Unit& reqUnit,
     150             :                           const Vector<MVDirection>& directions, 
     151             :                           const MeasRef<MDirection>& dirRef, 
     152             :                           const MVAngle& pixelLatSize, 
     153             :                           const MVAngle& pixelLongSize, 
     154             :                           const Vector<MVFrequency>& frequencies,
     155             :                           const MeasRef<MFrequency>& freqRef) const {
     156        4439 :   itsCompPtr->sample(samples, reqUnit,
     157             :                      directions, dirRef, pixelLatSize, pixelLongSize,
     158        4439 :                      frequencies, freqRef);
     159        4439 : }
     160             : 
     161     2128905 : Flux<Double> SkyComponent::visibility(const Vector<Double>& uvw,
     162             :                                       const Double& frequency) const {
     163     2128905 :   return itsCompPtr->visibility(uvw, frequency);
     164             : }
     165             : 
     166        5435 : void SkyComponent::visibility(Cube<DComplex>& visibilities,
     167             :                               const Matrix<Double>& uvws,
     168             :                               const Vector<Double>& frequencies) const {
     169        5435 :   itsCompPtr->visibility(visibilities, uvws, frequencies);
     170        5435 : }
     171             : 
     172        5840 : Bool SkyComponent::fromRecord(String& errorMessage, 
     173             :                               const RecordInterface& record) {
     174        5840 :   return itsCompPtr->fromRecord(errorMessage, record);
     175             : }
     176             : 
     177        6537 : Bool SkyComponent::toRecord(String& errorMessage,
     178             :                             RecordInterface& record) const {
     179        6537 :   return itsCompPtr->toRecord(errorMessage, record);
     180             : }
     181             : 
     182       11083 : SkyComponent SkyComponent::copy() const {
     183       11083 :   SkyComponent newComp(flux().copy(), shape(), spectrum());
     184       11083 :   newComp.label() = label();
     185       11083 :   newComp.optionalParameters() = optionalParameters();
     186       11083 :   return newComp;
     187             : }
     188             : 
     189         393 : void SkyComponent::fromPixel (Double& fluxRatio, const Vector<Double>& parameters,
     190             :                               const Unit& brightnessUnitIn,
     191             :                               const GaussianBeam& restoringBeam,
     192             :                               const CoordinateSystem& cSys,
     193             :                               ComponentType::Shape componentShape,
     194             :                               Stokes::StokesTypes stokes)
     195             : {
     196         393 :    itsCompPtr->fromPixel(fluxRatio, parameters, brightnessUnitIn, restoringBeam,
     197             :                          cSys, componentShape, stokes);
     198         393 : }
     199             : 
     200          58 : Vector<Double> SkyComponent::toPixel (const Unit& brightnessUnitIn,
     201             :                                       const GaussianBeam& restoringBeam,
     202             :                                       const CoordinateSystem& cSys,
     203             :                                       Stokes::StokesTypes stokes) const
     204             : {
     205             :    return itsCompPtr->toPixel(brightnessUnitIn, restoringBeam,
     206          58 :                               cSys, stokes);
     207             : }
     208             : 
     209             : 
     210             : 
     211             : 
     212           0 : Bool SkyComponent::ok() const {
     213           0 :   if (itsCompPtr.null()) {
     214           0 :     LogIO logErr(LogOrigin("SkyComponent", "ok()"));
     215             :     logErr << LogIO::SEVERE << "Internal pointer is not pointing to anything"
     216           0 :            << LogIO::POST;
     217           0 :     return false;
     218             :   }
     219           0 :   if (!itsCompPtr->ok()) {
     220           0 :     LogIO logErr(LogOrigin("SkyComponent", "ok()"));
     221             :     logErr << LogIO::SEVERE << "Component representation is not ok"
     222           0 :            << LogIO::POST;
     223           0 :     return false;
     224             :   }
     225           0 :   return true;
     226             : }
     227             : 
     228           0 : String SkyComponent::summarize(
     229             :         const DirectionCoordinate *const &dc, Bool longErrOnGreatCircle
     230             : ) const {
     231           0 :         ostringstream ldpar;
     232           0 :         if (shape().type()==ComponentType::LDISK) {
     233           0 :                 ldpar << " (limb-darkening exponent: "<<optionalParameters()(0) <<" )"<<endl;
     234             :         }
     235           0 :         ostringstream summary;
     236           0 :         summary << "SUMMARY OF COMPONENT " << label() << endl;
     237           0 :         summary << "Shape: " << shape().ident() << ldpar.str() <<endl;
     238           0 :         const Flux<Double> myFlux = flux();
     239           0 :         Quantum<Vector<std::complex<double> > > fluxValue;
     240           0 :         myFlux.value(fluxValue);
     241           0 :         summary << "Flux density: " << fluxValue << " +/- " << myFlux.errors() << endl;
     242           0 :         summary << "Spectral model: " << spectrum().ident() << endl;
     243           0 :         std::shared_ptr<Vector<Double>> pixCoords;
     244           0 :         summary << "Position: " <<  positionToString(pixCoords, dc, longErrOnGreatCircle) << endl;
     245           0 :         summary << "Size: " << endl << shape().sizeToString() << endl;
     246           0 :         return summary.str();
     247             : }
     248             : 
     249         393 : String SkyComponent::positionToString(
     250             :     std::shared_ptr<casacore::Vector<casacore::Double>>& pixelCoords,
     251             :         const DirectionCoordinate *const &dc ,Bool longErrOnGreatCircle
     252             : ) const {
     253         393 :     pixelCoords.reset();
     254             :         // FIXME essentially cut and paste of Gareth's python code. Needs work.
     255         786 :         ostringstream position;
     256         786 :         MDirection mdir = shape().refDirection();
     257             : 
     258         786 :         Quantity lat = mdir.getValue().getLat("rad");
     259         786 :         String latString = MVAngle(lat).string(MVAngle::ANGLE_CLEAN, 8);
     260             : 
     261         786 :         Quantity longitude = mdir.getValue().getLong("rad");
     262         786 :         String longString = MVTime(longitude).string(MVTime::TIME, 9);
     263             : 
     264         786 :         Quantity dLat = shape().refDirectionErrorLat();
     265         393 :         dLat.convert("rad");
     266             : 
     267         786 :         Quantity dLong = shape().refDirectionErrorLong();
     268         393 :         dLong.convert("rad");
     269             : 
     270             :         // Add error estimates to ra/dec strings if an error is given (either >0)
     271             : 
     272         393 :         uInt precision = 1;
     273         393 :         if ( dLong.getValue() != 0 || dLat.getValue() != 0 ) {
     274         393 :                 dLong.convert("s");
     275         393 :                 dLat.convert("arcsec");
     276         393 :                 Double drasec  = roundDouble(dLong.getValue());
     277         393 :                 Double ddecarcsec = roundDouble(dLat.getValue());
     278         786 :                 Vector<Double> dravec(2), ddecvec(2);
     279         393 :                 dravec.set(drasec);
     280         393 :                 ddecvec.set(ddecarcsec);
     281         393 :                 precision = precisionForValueErrorPairs(dravec,ddecvec);
     282         393 :                 longString = MVTime(longitude).string(MVTime::TIME, 6+precision);
     283         393 :                 latString =  MVAngle(lat).string(MVAngle::ANGLE, 6+precision);
     284             :         }
     285         393 :         std::pair<String, String> labels = _axisLabels(dc);
     286         393 :         position << "Position ---" << endl;
     287         393 :         position << "       --- " << labels.first << "   " << longString;
     288         393 :         if (dLong.getValue() == 0) {
     289           0 :                 position << " (fixed)" << endl;
     290             :         }
     291             :         else {
     292         786 :                 Quantity timeError = longErrOnGreatCircle ? dLong/cos(lat) : dLong;
     293         393 :                 position << " +/- " << std::fixed
     294         393 :                         << std::setprecision(precision) << timeError << " ("
     295         786 :                         << dLong.getValue("arcsec") << " arcsec"
     296             :                         << (longErrOnGreatCircle ? " along great circle" : "")
     297         393 :                         << ")" << endl;
     298             :         }
     299         393 :         position << "       --- " << labels.second << " " << latString;
     300         393 :         if (dLat.getValue() == 0) {
     301           0 :                 position << " (fixed)" << endl;
     302             :         }
     303             :         else {
     304         393 :                 position << " +/- " << dLat << endl;
     305             :         }
     306         393 :         if (dc) {
     307         786 :                 const Vector<String> units = dc->worldAxisUnits();
     308         786 :                 Vector<Double> world(dc->nWorldAxes(), 0);
     309         393 :                 world[0] = longitude.getValue(units[0]);
     310         393 :                 world[1] = lat.getValue(units[1]);
     311             :                 // TODO do the pixel computations in another method
     312         393 :                 pixelCoords.reset(new Vector<Double>());
     313         393 :                 if (dc->toPixel(*pixelCoords, world)) {
     314         786 :                         Vector<Double> increment = dc->increment();
     315         393 :                         Double longPixErr = dLong.getValue() == 0
     316         393 :                                 ? 0 : abs(dLong.getValue(units[0])/increment[0]);
     317         393 :                         Double latPixErr = dLat.getValue() == 0
     318         393 :                                 ? 0 : abs(dLat.getValue(units[1])/increment[1]);
     319         786 :                         Vector<Double> longPix(2), latPix(2);
     320         393 :                         longPix.set(roundDouble(longPixErr));
     321         393 :                         latPix.set(roundDouble(latPixErr));
     322         393 :                         precision = precisionForValueErrorPairs(longPix, latPix);
     323         393 :                         position << std::fixed <<  std::setprecision(precision);
     324         393 :                         position << "       --- " << labels.first << " " << (*pixelCoords)[0];
     325         393 :                         if (dLong.getValue() == 0) {
     326           0 :                                 position << " (fixed)" << endl;
     327             :                         }
     328             :                         else {
     329         393 :                                 position << " +/- " << longPixErr << " pixels" << endl;
     330             :                         }
     331         393 :                         position << "       --- " << labels.second << " " << (*pixelCoords)[1];
     332         393 :                         if (dLat.getValue() == 0) {
     333           0 :                                 position << " (fixed)" << endl;
     334             :                         }
     335             :                         else {
     336         393 :                                 position << " +/- " << latPixErr << " pixels" << endl;
     337             :                         }
     338             :                 }
     339             :                 else {
     340           0 :                         position << "unable to determine position in pixels:" << dc->errorMessage() << endl;
     341             :                 }
     342             :         }
     343         786 :         return position.str();
     344             : }
     345             : 
     346         393 : std::pair<String, String> SkyComponent::_axisLabels(
     347             :         const DirectionCoordinate *const &dc
     348             : ) {
     349         393 :         std::pair<String, String> labels;
     350         393 :         if (dc) {
     351         786 :                 Vector<String> names = dc->worldAxisNames();
     352        1179 :                 for (uInt i=0; i<2; i++) {
     353        1572 :                         String label;
     354         786 :                         names[i].downcase();
     355         786 :                         if (names[i] == "right ascension") {
     356         338 :                                 label = "ra:";
     357             :                         }
     358         448 :                         else if (names[i] == "declination") {
     359         338 :                                 label = "dec:";
     360             :                         }
     361         110 :                         else if (names[i] == "longitude") {
     362          55 :                                 label = "long:";
     363             :                         }
     364          55 :                         else if (names[i] == "latitude") {
     365          55 :                                 label = "lat:";
     366             :                         }
     367             :                         else {
     368           0 :                                 label = names[i] + ":";
     369             :                         }
     370         786 :                         if (i == 0) {
     371         393 :                                 labels.first = label;
     372             :                         }
     373             :                         else {
     374         393 :                                 labels.second = label;
     375             :                         }
     376             :                 }
     377             :         }
     378             :         else {
     379           0 :                 labels.first  = "long:";
     380           0 :                 labels.second = "lat: ";
     381             :         }
     382             :         typedef std::string::size_type size_type;
     383         393 :         size_type f = labels.first.size();
     384         393 :         size_type s = labels.second.size();
     385         393 :         if (f > s) {
     386          55 :                 size_type d = f - s;
     387         110 :                 for (size_type i=0; i<d ;i++) {
     388          55 :                         labels.second += " ";
     389             :                 }
     390             :         }
     391         338 :         else if (f < s) {
     392         338 :                 size_type d = s - f;
     393         676 :                 for (size_type i=0; i<d ;i++) {
     394         338 :                         labels.first += " ";
     395             :                 }
     396             :         }
     397         393 :         return labels;
     398             : }
     399             : 
     400             : }
     401             : 

Generated by: LCOV version 1.16