LCOV - code coverage report
Current view: top level - components/ComponentModels - SpectralModel.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 113 153 73.9 %
Date: 2024-12-11 20:54:31 Functions: 18 20 90.0 %

          Line data    Source code
       1             : //# SpectralModel.cc:
       2             : //# Copyright (C) 1998,1999,2000,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 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: SpectralModel.cc 20652 2009-07-06 05:04:32Z Malte.Marquarding $
      27             : 
      28             : #include <components/ComponentModels/SpectralModel.h>
      29             : #include <casacore/casa/Containers/Record.h>
      30             : #include <casacore/casa/Containers/RecordFieldId.h>
      31             : #include <casacore/casa/Containers/RecordInterface.h>
      32             : #include <casacore/casa/Exceptions/Error.h>
      33             : #include <casacore/casa/Arrays/IPosition.h>
      34             : #include <casacore/measures/Measures/MeasureHolder.h>
      35             : #include <casacore/measures/Measures/MFrequency.h>
      36             : #include <casacore/measures/Measures/MCFrequency.h>
      37             : #include <casacore/measures/Measures/MeasConvert.h>
      38             : #include <casacore/casa/Quanta/QuantumHolder.h>
      39             : #include <casacore/casa/Quanta/Quantum.h>
      40             : #include <casacore/casa/Utilities/Assert.h>
      41             : #include <casacore/casa/Utilities/DataType.h>
      42             : #include <casacore/casa/BasicSL/String.h>
      43             : #include <casacore/casa/Logging/LogIO.h>
      44             : #include <casacore/casa/Logging/LogOrigin.h>
      45             : #include <iostream>
      46             : 
      47             : using namespace casacore;
      48             : namespace casa { //# NAMESPACE CASA - BEGIN
      49             : 
      50      159279 : SpectralModel::SpectralModel()
      51      159279 :   :itsRefFreq(Quantum<Double>(1, "GHz"), MFrequency::DEFAULT),
      52      159279 :    itsFreqUnit("GHz"),
      53      318558 :    itsFreqErr(0, itsFreqUnit)
      54             : {
      55      159279 :   DebugAssert(SpectralModel::ok(), AipsError);
      56      159279 : }
      57             : 
      58          92 : SpectralModel::SpectralModel(const MFrequency& refFreq, const Unit& freqUnit)
      59          92 :   :itsRefFreq(refFreq),
      60          92 :    itsFreqUnit(freqUnit),
      61         184 :    itsFreqErr(0, itsFreqUnit)
      62             : {
      63          92 :   DebugAssert(SpectralModel::ok(), AipsError);
      64          92 : }
      65             : 
      66       56873 : SpectralModel::SpectralModel(const SpectralModel& other) 
      67             :   :RecordTransformable(),
      68       56873 :    itsRefFreq(other.itsRefFreq),
      69       56873 :    itsFreqUnit(other.itsFreqUnit),
      70      113746 :    itsFreqErr(other.itsFreqErr)
      71             : {
      72       56873 :   DebugAssert(SpectralModel::ok(), AipsError);
      73       56873 : }
      74             : 
      75       37710 : SpectralModel& SpectralModel::operator=(const SpectralModel& other) {
      76       37710 :   if (this != &other) {
      77       37710 :     itsRefFreq = other.itsRefFreq;
      78       37710 :     itsFreqUnit = other.itsFreqUnit;
      79       37710 :     itsFreqErr = other.itsFreqErr;
      80             :   }
      81       37710 :   DebugAssert(SpectralModel::ok(), AipsError);
      82       37710 :   return *this;
      83             : }
      84             : 
      85      216243 : SpectralModel::~SpectralModel() {
      86      216243 : }
      87             : 
      88        2695 : const String& SpectralModel::ident() const {
      89        2695 :   DebugAssert(SpectralModel::ok(), AipsError);
      90        2695 :   static String typeString;
      91        2695 :   typeString = ComponentType::name(type());
      92        2695 :   return typeString;
      93             : }
      94             : 
      95      504887 : const MFrequency& SpectralModel::refFrequency() const {
      96      504887 :   DebugAssert(SpectralModel::ok(), AipsError);
      97      504887 :   return itsRefFreq;
      98             : }
      99             : 
     100       44588 : Double SpectralModel::refFreqInFrame(const MFrequency::Ref& elframe) const {
     101       44588 :     const MFrequency& refFreq(refFrequency());
     102             :     Double nu0;
     103       44588 :     Bool stupidTransform = (elframe.getType() == MFrequency::REST) ||  (elframe.getType() == MFrequency::N_Types) || (refFreq.getRef().getType() == MFrequency::REST) ||  (refFreq.getRef().getType() == MFrequency::N_Types);
     104       44588 :   if (elframe != refFreq.getRef() && !stupidTransform) {
     105             :     try{
     106         859 :       nu0 = (MFrequency::Convert(refFreq, elframe))().getValue().getValue();
     107             :     }
     108           0 :     catch(...){
     109           0 :       throw(AipsError(String("Cannot transform frequency from ") +  MFrequency::showType(elframe.getType()) + String(" to ") + MFrequency::showType(refFreq.getRef().getType())));
     110           0 :     }
     111             :   } else {
     112       43729 :     nu0 = refFreq.getValue().getValue();
     113             :   }
     114             : 
     115       44588 :   return nu0;
     116             : }
     117             : 
     118      115623 : void SpectralModel::setRefFrequency(const MFrequency& newRefFreq) {
     119      115623 :   itsRefFreq = newRefFreq;
     120      115623 :   DebugAssert(SpectralModel::ok(), AipsError);
     121      115623 : }
     122             : 
     123       10047 : const Unit& SpectralModel::frequencyUnit() const {  
     124       10047 :   DebugAssert(SpectralModel::ok(), AipsError);
     125       10047 :   return itsFreqUnit;
     126             : }
     127             : 
     128          37 : void SpectralModel::convertFrequencyUnit(const Unit& freqUnit) {
     129          37 :   itsFreqUnit = freqUnit;
     130          37 :   DebugAssert(SpectralModel::ok(), AipsError);
     131          37 : }
     132             : 
     133        1463 : void SpectralModel::setRefFrequencyError(const Quantum<Double>& newRefFreqErr){
     134        1463 :   if (badError(newRefFreqErr)) {
     135           0 :     LogIO logErr(LogOrigin("SpectralModel", "setRefFrequencyError"));
     136             :     logErr << "The errors must be positive values with units like Hz"
     137           0 :            << LogIO::EXCEPTION;
     138           0 :   }
     139        1463 :   itsFreqErr = newRefFreqErr;
     140        1463 :   DebugAssert(SpectralModel::ok(), AipsError);
     141        1463 : }
     142             : 
     143        2695 : const Quantum<Double>& SpectralModel::refFrequencyError() const {
     144        2695 :   return itsFreqErr;
     145             : }
     146             : 
     147           0 : void  SpectralModel::sample(Vector<Double>& scale, 
     148             :                             const Vector<MFrequency::MVType>& frequencies, 
     149             :                             const MFrequency::Ref& refFrame) const {
     150           0 :   DebugAssert(SpectralModel::ok(), AipsError);
     151           0 :   const uInt nSamples = frequencies.nelements();
     152           0 :   DebugAssert(scale.nelements() == nSamples, AipsError);
     153             :   
     154           0 :   for (uInt i = 0; i < nSamples; i++) {
     155           0 :     scale(i) = sample(MFrequency(frequencies(i), refFrame));
     156             :   }
     157           0 : }
     158             : 
     159       79438 : Bool SpectralModel::fromRecord(String& errorMessage, 
     160             :                                   const RecordInterface& record) {
     161       79438 :   const String freqString("frequency");
     162       79438 :   if (!record.isDefined(freqString)) {
     163           0 :     errorMessage += "The 'frequency' field does not exist\n";
     164           0 :     return false;
     165             :   }
     166       79438 :   const RecordFieldId frequency(freqString);
     167       79438 :   if (record.dataType(frequency) != TpRecord) {
     168           0 :     if ((record.dataType(frequency) == TpString) && 
     169           0 :         (record.shape(frequency) == IPosition(1,1)) &&
     170           0 :         (record.asString(frequency) == String("current"))) {
     171           0 :       return true;
     172             :     } else {
     173           0 :       errorMessage += "The 'frequency' field must be a record\n";
     174           0 :       errorMessage += "or the string 'current' (to use the current value)\n";
     175           0 :       return false;
     176             :     }
     177             :   }
     178       79438 :   const Record& freqRecord = record.asRecord(frequency);
     179       79438 :   MeasureHolder mh;
     180       79438 :   if (!mh.fromRecord(errorMessage, freqRecord)) {
     181           0 :     errorMessage += "Could not parse the reference frequency\n";
     182           0 :     return false;
     183             :   }
     184       79438 :   if (!mh.isMFrequency()) {
     185           0 :     errorMessage += "The reference frequency is not a frequency measure\n";
     186           0 :     return false;
     187             :   }
     188       79438 :   SpectralModel::setRefFrequency(mh.asMFrequency());
     189       79438 :   return true;
     190       79438 : }
     191             : 
     192       10047 : Bool SpectralModel::toRecord(String& errorMessage,
     193             :                              RecordInterface& record) const {
     194       10047 :   DebugAssert(SpectralModel::ok(), AipsError);
     195       10047 :   record.define(RecordFieldId("type"), ComponentType::name(type()));
     196       10047 :   Record freqRecord;
     197       10047 :   const MeasureHolder mh(refFrequency());
     198       10047 :   if (!mh.toRecord(errorMessage, freqRecord)) {
     199           0 :     errorMessage += "Could not convert the reference frequency to a record\n";
     200           0 :     return false;
     201             :   }
     202       10047 :   const String m0String("m0");
     203       10047 :   if (freqRecord.isDefined(m0String)) {
     204       10047 :     const RecordFieldId m0(m0String);
     205       10047 :     if (freqRecord.dataType(m0) == TpRecord) {
     206       10047 :       Record m0Rec = freqRecord.asRecord(m0);
     207       10047 :       QuantumHolder qh;
     208       10047 :       String error;
     209       10047 :       if (qh.fromRecord(error, m0Rec) && qh.isQuantumDouble()) {
     210       10047 :         Quantum<Double> q = qh.asQuantumDouble();
     211       10047 :         q.convert(frequencyUnit());
     212       10047 :         qh = QuantumHolder(q);
     213       10047 :         if (qh.toRecord(error, m0Rec)) {
     214       10047 :           freqRecord.defineRecord(m0, m0Rec);
     215             :         }
     216       10047 :       }
     217       10047 :     }
     218       10047 :   }
     219       10047 :   record.defineRecord(RecordFieldId("frequency"), freqRecord);
     220       10047 :   return true;
     221       10047 : }
     222             : 
     223       77975 : ComponentType::SpectralShape SpectralModel::
     224             : getType(String& errorMessage, const RecordInterface& record) {
     225       77975 :   const String typeString("type");
     226       77975 :   if (!record.isDefined(typeString)) {
     227             :     errorMessage += 
     228           0 :       String("\nThe record does not have a 'type' field.");
     229           0 :     return ComponentType::UNKNOWN_SPECTRAL_SHAPE;
     230             :   }
     231       77975 :   const RecordFieldId type(typeString);
     232       77975 :   if (record.dataType(type) != TpString) {
     233           0 :     errorMessage += String("\nThe 'type' field in the spectrum record,")
     234           0 :       + String("must be a String");
     235           0 :     return ComponentType::UNKNOWN_SPECTRAL_SHAPE;
     236             :   }      
     237       77975 :   if (record.shape(type) != IPosition(1,1)) {
     238           0 :     errorMessage += String("The 'type' field, in the spectrum record,") + 
     239           0 :       String(" must have only 1 element\n");
     240           0 :     return ComponentType::UNKNOWN_SPECTRAL_SHAPE;
     241             :   }      
     242       77975 :   const String& typeVal = record.asString(type);
     243       77975 :   return ComponentType::spectralShape(typeVal);
     244       77975 : }
     245             : 
     246     3861136 : Bool SpectralModel::ok() const {
     247     3861136 :   if (itsFreqUnit != Unit("GHz")) {
     248           0 :     LogIO logErr(LogOrigin("SpectralModel", "ok()"));
     249             :     logErr << LogIO::SEVERE << "The reference frequency has units with " 
     250             :            << endl << " different dimensions than the Hz."
     251           0 :            << LogIO::POST;
     252           0 :     return false;
     253           0 :   }
     254     3861136 :   return true;
     255             : }
     256             : 
     257        1463 : Bool SpectralModel::badError(const Quantum<Double>& quantum) {
     258        1463 :   const UnitVal hz(1, "Hz");
     259        2926 :   return !(quantum.check(hz)) || (quantum.getValue() < 0.0);
     260        1463 : }
     261             : 
     262             : // Local Variables: 
     263             : // compile-command: "gmake SpectralModel"
     264             : // End: 
     265             : 
     266             : } //# NAMESPACE CASA - END
     267             : 

Generated by: LCOV version 1.16