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

Generated by: LCOV version 1.16