LCOV - code coverage report
Current view: top level - components/ComponentModels - SpectralModel.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 107 153 69.9 %
Date: 2024-10-04 18:58:15 Functions: 17 20 85.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       73418 : SpectralModel::SpectralModel()
      51       73418 :   :itsRefFreq(Quantum<Double>(1, "GHz"), MFrequency::DEFAULT),
      52       73418 :    itsFreqUnit("GHz"),
      53      146836 :    itsFreqErr(0, itsFreqUnit)
      54             : {
      55       73418 :   DebugAssert(SpectralModel::ok(), AipsError);
      56       73418 : }
      57             : 
      58           0 : SpectralModel::SpectralModel(const MFrequency& refFreq, const Unit& freqUnit)
      59           0 :   :itsRefFreq(refFreq),
      60           0 :    itsFreqUnit(freqUnit),
      61           0 :    itsFreqErr(0, itsFreqUnit)
      62             : {
      63           0 :   DebugAssert(SpectralModel::ok(), AipsError);
      64           0 : }
      65             : 
      66       14078 : SpectralModel::SpectralModel(const SpectralModel& other) 
      67             :   :RecordTransformable(),
      68       14078 :    itsRefFreq(other.itsRefFreq),
      69       14078 :    itsFreqUnit(other.itsFreqUnit),
      70       28156 :    itsFreqErr(other.itsFreqErr)
      71             : {
      72       14078 :   DebugAssert(SpectralModel::ok(), AipsError);
      73       14078 : }
      74             : 
      75        7986 : SpectralModel& SpectralModel::operator=(const SpectralModel& other) {
      76        7986 :   if (this != &other) {
      77        7986 :     itsRefFreq = other.itsRefFreq;
      78        7986 :     itsFreqUnit = other.itsFreqUnit;
      79        7986 :     itsFreqErr = other.itsFreqErr;
      80             :   }
      81        7986 :   DebugAssert(SpectralModel::ok(), AipsError);
      82        7986 :   return *this;
      83             : }
      84             : 
      85       87495 : SpectralModel::~SpectralModel() {
      86       87495 : }
      87             : 
      88         129 : const String& SpectralModel::ident() const {
      89         129 :   DebugAssert(SpectralModel::ok(), AipsError);
      90         129 :   static String typeString;
      91         129 :   typeString = ComponentType::name(type());
      92         129 :   return typeString;
      93             : }
      94             : 
      95      103133 : const MFrequency& SpectralModel::refFrequency() const {
      96      103133 :   DebugAssert(SpectralModel::ok(), AipsError);
      97      103133 :   return itsRefFreq;
      98             : }
      99             : 
     100        8470 : Double SpectralModel::refFreqInFrame(const MFrequency::Ref& elframe) const {
     101        8470 :     const MFrequency& refFreq(refFrequency());
     102             :     Double nu0;
     103        8470 :     Bool stupidTransform = (elframe.getType() == MFrequency::REST) ||  (elframe.getType() == MFrequency::N_Types) || (refFreq.getRef().getType() == MFrequency::REST) ||  (refFreq.getRef().getType() == MFrequency::N_Types);
     104        8470 :   if (elframe != refFreq.getRef() && !stupidTransform) {
     105             :     try{
     106         726 :       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        7744 :     nu0 = refFreq.getValue().getValue();
     113             :   }
     114             : 
     115        8470 :   return nu0;
     116             : }
     117             : 
     118       47086 : void SpectralModel::setRefFrequency(const MFrequency& newRefFreq) {
     119       47086 :   itsRefFreq = newRefFreq;
     120       47086 :   DebugAssert(SpectralModel::ok(), AipsError);
     121       47086 : }
     122             : 
     123        1414 : const Unit& SpectralModel::frequencyUnit() const {  
     124        1414 :   DebugAssert(SpectralModel::ok(), AipsError);
     125        1414 :   return itsFreqUnit;
     126             : }
     127             : 
     128           1 : void SpectralModel::convertFrequencyUnit(const Unit& freqUnit) {
     129           1 :   itsFreqUnit = freqUnit;
     130           1 :   DebugAssert(SpectralModel::ok(), AipsError);
     131           1 : }
     132             : 
     133         158 : void SpectralModel::setRefFrequencyError(const Quantum<Double>& newRefFreqErr){
     134         158 :   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         158 :   itsFreqErr = newRefFreqErr;
     140         158 :   DebugAssert(SpectralModel::ok(), AipsError);
     141         158 : }
     142             : 
     143         129 : const Quantum<Double>& SpectralModel::refFrequencyError() const {
     144         129 :   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       38541 : Bool SpectralModel::fromRecord(String& errorMessage, 
     160             :                                   const RecordInterface& record) {
     161       38541 :   const String freqString("frequency");
     162       38541 :   if (!record.isDefined(freqString)) {
     163           0 :     errorMessage += "The 'frequency' field does not exist\n";
     164           0 :     return false;
     165             :   }
     166       38541 :   const RecordFieldId frequency(freqString);
     167       38541 :   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       38541 :   const Record& freqRecord = record.asRecord(frequency);
     179       38541 :   MeasureHolder mh;
     180       38541 :   if (!mh.fromRecord(errorMessage, freqRecord)) {
     181           0 :     errorMessage += "Could not parse the reference frequency\n";
     182           0 :     return false;
     183             :   }
     184       38541 :   if (!mh.isMFrequency()) {
     185           0 :     errorMessage += "The reference frequency is not a frequency measure\n";
     186           0 :     return false;
     187             :   }
     188       38541 :   SpectralModel::setRefFrequency(mh.asMFrequency());
     189       38541 :   return true;
     190       38541 : }
     191             : 
     192        1414 : Bool SpectralModel::toRecord(String& errorMessage,
     193             :                              RecordInterface& record) const {
     194        1414 :   DebugAssert(SpectralModel::ok(), AipsError);
     195        1414 :   record.define(RecordFieldId("type"), ComponentType::name(type()));
     196        1414 :   Record freqRecord;
     197        1414 :   const MeasureHolder mh(refFrequency());
     198        1414 :   if (!mh.toRecord(errorMessage, freqRecord)) {
     199           0 :     errorMessage += "Could not convert the reference frequency to a record\n";
     200           0 :     return false;
     201             :   }
     202        1414 :   const String m0String("m0");
     203        1414 :   if (freqRecord.isDefined(m0String)) {
     204        1414 :     const RecordFieldId m0(m0String);
     205        1414 :     if (freqRecord.dataType(m0) == TpRecord) {
     206        1414 :       Record m0Rec = freqRecord.asRecord(m0);
     207        1414 :       QuantumHolder qh;
     208        1414 :       String error;
     209        1414 :       if (qh.fromRecord(error, m0Rec) && qh.isQuantumDouble()) {
     210        1414 :         Quantum<Double> q = qh.asQuantumDouble();
     211        1414 :         q.convert(frequencyUnit());
     212        1414 :         qh = QuantumHolder(q);
     213        1414 :         if (qh.toRecord(error, m0Rec)) {
     214        1414 :           freqRecord.defineRecord(m0, m0Rec);
     215             :         }
     216        1414 :       }
     217        1414 :     }
     218        1414 :   }
     219        1414 :   record.defineRecord(RecordFieldId("frequency"), freqRecord);
     220        1414 :   return true;
     221        1414 : }
     222             : 
     223       38383 : ComponentType::SpectralShape SpectralModel::
     224             : getType(String& errorMessage, const RecordInterface& record) {
     225       38383 :   const String typeString("type");
     226       38383 :   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       38383 :   const RecordFieldId type(typeString);
     232       38383 :   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       38383 :   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       38383 :   const String& typeVal = record.asString(type);
     243       38383 :   return ComponentType::spectralShape(typeVal);
     244       38383 : }
     245             : 
     246      576955 : Bool SpectralModel::ok() const {
     247      576955 :   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      576955 :   return true;
     255             : }
     256             : 
     257         158 : Bool SpectralModel::badError(const Quantum<Double>& quantum) {
     258         158 :   const UnitVal hz(1, "Hz");
     259         316 :   return !(quantum.check(hz)) || (quantum.getValue() < 0.0);
     260         158 : }
     261             : 
     262             : // Local Variables: 
     263             : // compile-command: "gmake SpectralModel"
     264             : // End: 
     265             : 
     266             : } //# NAMESPACE CASA - END
     267             : 

Generated by: LCOV version 1.16