LCOV - code coverage report
Current view: top level - components/SpectralComponents - SpectralListFactory.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 125 148 84.5 %
Date: 2024-12-11 20:54:31 Functions: 4 4 100.0 %

          Line data    Source code
       1             : //# Copyright (C) 1993,1994,1995,1996,1999,2001
       2             : //# Associated Universities, Inc. Washington DC, USA.
       3             : //#
       4             : //# This library is free software; you can redistribute it and/or modify it
       5             : //# under the terms of the GNU Library General Public License as published by
       6             : //# the Free Software Foundation; either version 2 of the License, or (at your
       7             : //# option) any later version.
       8             : //#
       9             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      10             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      11             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      12             : //# License for more details.
      13             : //#
      14             : //# You should have received a copy of the GNU Library General Public License
      15             : //# along with this library; if not, write to the Free Software Foundation,
      16             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      17             : //#
      18             : //# Correspondence concerning AIPS++ should be addressed as follows:
      19             : //#        Internet email: casa-feedback@nrao.edu.
      20             : //#        Postal address: AIPS++ Project Office
      21             : //#                        National Radio Astronomy Observatory
      22             : //#                        520 Edgemont Road
      23             : //#                        Charlottesville, VA 22903-2475 USA
      24             : //#
      25             : 
      26             : #include <components/SpectralComponents/SpectralListFactory.h>
      27             : 
      28             : #include <components/SpectralComponents/GaussianSpectralElement.h>
      29             : #include <components/SpectralComponents/GaussianMultipletSpectralElement.h>
      30             : #include <components/SpectralComponents/LorentzianSpectralElement.h>
      31             : #include <components/SpectralComponents/PowerLogPolynomialSpectralElement.h>
      32             : #include <components/SpectralComponents/LogTransformedPolynomialSpectralElement.h>
      33             : 
      34             : #include <stdcasa/StdCasa/CasacSupport.h>
      35             : 
      36             : using namespace casacore;
      37             : using namespace casac;
      38             : 
      39             : using namespace casacore;
      40             : namespace casa {
      41             : 
      42          93 : SpectralList SpectralListFactory::create(
      43             :         LogIO& log, const variant& pampest,
      44             :         const variant& pcenterest, const variant& pfwhmest,
      45             :         const variant& pfix, const variant& gmncomps,
      46             :         const variant& gmampcon, const variant& gmcentercon,
      47             :         const variant& gmfwhmcon, const vector<double>& gmampest,
      48             :         const vector<double>& gmcenterest, const vector<double>& gmfwhmest,
      49             :         const variant& gmfix, const variant& pfunc,
      50             :         const variant& plpest, const variant& plpfix,
      51             :         const variant& ltpest, const variant& ltpfix
      52             : ) {
      53          93 :         vector<double> myampest = toVectorDouble(pampest, "pampest");
      54          93 :         vector<double> mycenterest = toVectorDouble(pcenterest, "pcenterest");
      55          93 :         vector<double> myfwhmest = toVectorDouble(pfwhmest, "pfwhmest");
      56          93 :         vector<string> myfix = toVectorString(pfix, "pfix");
      57          93 :         vector<string> myfunc = toVectorString(pfunc, "pfunc");
      58          93 :         vector<double> myplpest = toVectorDouble(plpest, "plpest");
      59          93 :         vector<bool> myplpfix = toVectorBool(plpfix, "plpfix");
      60          93 :         vector<double> myltpest = toVectorDouble(ltpest, "ltpest");
      61          93 :         vector<bool> myltpfix = toVectorBool(ltpfix, "ltpfix");
      62             : 
      63          93 :         vector<int> mygmncomps = gmncomps.type() == variant::INT
      64          93 :                 && gmncomps.toInt() == 0
      65          93 :                 ? vector<int>(0)
      66         279 :                 : toVectorInt(gmncomps, "gmncomps");
      67          93 :         vector<double> mygmampcon = toVectorDouble(gmampcon, "gmampcon");
      68          93 :         vector<double> mygmcentercon = toVectorDouble(gmcentercon, "gmcentercon");
      69          93 :         vector<double> mygmfwhmcon = toVectorDouble(gmfwhmcon, "gmfwhmcon");
      70          93 :         vector<string> mygmfix = toVectorString(gmfix, "gmfix");
      71             :         Bool makeSpectralList = (
      72          93 :                 mygmncomps.size() + myplpest.size() + myltpest.size() > 0
      73         240 :                 || ! (
      74          75 :                         myampest.size() == 0
      75          72 :                         && mycenterest.size() == 0
      76          72 :                         && myfwhmest.size() == 0
      77             :                 )
      78          93 :         );
      79          93 :         SpectralList spectralList;
      80          93 :         Bool gfixSpecified = (myfix.size() > 0);
      81          93 :         if (! makeSpectralList) {
      82          72 :                 if (gfixSpecified) {
      83             :                         log << "The fix array is specified but no corresponding estimates are "
      84             :                                 << "set via ampest, centerest, and fwhmest. The fix array will be ignored."
      85           0 :                                 << LogIO::WARN;
      86             :                 }
      87          72 :                 return spectralList;
      88             :         }
      89          21 :         uInt mynpcf = myampest.size();
      90          21 :         if (myfunc.size() == 0) {
      91          20 :                 myfunc.resize(myampest.size(), "G");
      92             :         }
      93          21 :         ThrowIf(
      94             :                 mycenterest.size() != mynpcf
      95             :                 || myfwhmest.size() != mynpcf
      96             :                 || myfunc.size() != mynpcf,
      97             :                 "pampest, pcenterest, pfwhmest, and pfunc arrays "
      98             :                 "must all be the same length"
      99             :         );
     100          21 :         ThrowIf(
     101             :                 gfixSpecified && myfix.size() != mynpcf,
     102             :                 "If the gfix array is specified the number of "
     103             :                 "elements it has must be the same as the number of elements "
     104             :                 "in the ampest array even if some elements are empty strings"
     105             :         );
     106          21 :         if (mygmncomps.size() > 0) {
     107           2 :                 _addGaussianMultiplets(
     108             :                         spectralList, log, mygmncomps, mygmampcon,
     109             :                         mygmcentercon, mygmfwhmcon,
     110             :                         gmampest, gmcenterest, gmfwhmest,
     111             :                         mygmfix
     112             :                 );
     113             :         }
     114          27 :         for (uInt i=0; i<mynpcf; i++) {
     115           6 :                 String func(myfunc[i]);
     116           6 :                 func.upcase();
     117           6 :                 Bool doGauss = func.startsWith("G");
     118           6 :                 Bool doLorentz = func.startsWith("L");
     119           6 :                 if (! doGauss && ! doLorentz) {
     120           0 :                         log << myfunc[i] << " does not minimally match 'gaussian' or 'lorentzian'"
     121           0 :                                 << LogIO::EXCEPTION;
     122             :                 }
     123             :                 std::unique_ptr<PCFSpectralElement> pcf(
     124             :                         doGauss
     125             :                                 ? dynamic_cast<PCFSpectralElement*>(
     126             :                                         new GaussianSpectralElement(
     127           4 :                                                 myampest[i], mycenterest[i],
     128           4 :                                                 GaussianSpectralElement::sigmaFromFWHM(myfwhmest[i])
     129           4 :                                         )
     130             :                                 )
     131             :                                 : doLorentz
     132           4 :                                     ? dynamic_cast<PCFSpectralElement*>(
     133             :                                         new LorentzianSpectralElement(
     134           2 :                                                 myampest[i], mycenterest[i], myfwhmest[i]
     135           2 :                                                 )
     136             :                                           )
     137             :                                     : 0
     138          16 :                         );
     139           6 :                 if (gfixSpecified) {
     140           0 :                         pcf->fixByString(myfix[i]);
     141             :                 }
     142           6 :                 if (! spectralList.add(*pcf)) {
     143             :                         log << "Unable to add element to spectral list"
     144           0 :                                 << LogIO::EXCEPTION;
     145             :                 }
     146           6 :         }
     147          21 :         if (myplpest.size() > 0) {
     148          11 :                 _addPowerLogPolynomial(
     149             :                         spectralList, log, myplpest, myplpfix
     150             :                 );
     151             :         }
     152          21 :         if (myltpest.size() > 0) {
     153           5 :                 _addLogTransformedPolynomial(
     154             :                         spectralList, myltpest, myltpfix
     155             :                 );
     156             :         }
     157          21 :         return spectralList;
     158          93 : }
     159             : 
     160           2 : void SpectralListFactory::_addGaussianMultiplets(
     161             :         SpectralList& spectralList,
     162             :         LogIO& log,
     163             :         const vector<int>& mygmncomps,
     164             :         vector<double>& mygmampcon,
     165             :         vector<double>& mygmcentercon,
     166             :         vector<double>& mygmfwhmcon,
     167             :         const vector<double>& gmampest,
     168             :         const vector<double>& gmcenterest, const vector<double>& gmfwhmest,
     169             :         const vector<string>& mygmfix
     170             : ) {
     171           2 :         uInt sum = 0;
     172           4 :         for (uInt i=0; i<mygmncomps.size(); i++) {
     173           2 :                 if (mygmncomps[i] <= 0) {
     174           0 :                         log << "All elements of gmncomps must be greater than 0" << LogIO::EXCEPTION;
     175             :                 }
     176           2 :                 sum += mygmncomps[i];
     177             :         }
     178           2 :         if (gmampest.size() != sum) {
     179             :                 log << "gmampest must have exactly "
     180           0 :                         << sum << " elements" << LogIO::EXCEPTION;
     181             :         }
     182           2 :         if (gmcenterest.size() != sum) {
     183             :                 log << "gmcenterest must have exactly "
     184           0 :                                 << sum << " elements" << LogIO::EXCEPTION;
     185             :         }
     186           2 :         if (gmfwhmest.size() != sum) {
     187             :                 log << "gmfwhmest must have exactly "
     188           0 :                         << sum << " elements" << LogIO::EXCEPTION;
     189             :         }
     190           2 :         if (mygmfix.size() > 0 && mygmfix.size() != sum) {
     191             :                 log << "gmfwhmest must have either zero or " << sum
     192             :                         << " elements, even if some are empty strings."
     193           0 :                         << LogIO::EXCEPTION;
     194             :         }
     195           2 :         uInt nConstraints = sum - mygmncomps.size();
     196           2 :         if (mygmampcon.size() == 0) {
     197           0 :                 mygmampcon = vector<double>(nConstraints, 0);
     198             :         }
     199           2 :         else if (
     200           2 :                 mygmampcon.size() > 0
     201           2 :                 && mygmampcon.size() != nConstraints
     202             :         ) {
     203             :                 log << "If specified, gmampcon must have exactly "
     204             :                         << nConstraints << " elements, even if some are zero"
     205           0 :                         << LogIO::EXCEPTION;
     206             :         }
     207           2 :         if (mygmcentercon.size() == 0) {
     208           0 :                 mygmcentercon = vector<double>(nConstraints, 0);
     209             :         }
     210           2 :         else if (
     211           2 :                 mygmcentercon.size() > 0
     212           2 :                 && mygmcentercon.size() != nConstraints
     213             :         ) {
     214             :                 log << "If specified, gmcentercon must have exactly "
     215             :                         << nConstraints << " elements, even if some are zero"
     216           0 :                         << LogIO::EXCEPTION;
     217             :         }
     218           2 :         if (mygmfwhmcon.size() == 0) {
     219           2 :                 mygmfwhmcon = vector<double>(nConstraints, 0);
     220             :         }
     221           0 :         else if (
     222           0 :                 mygmfwhmcon.size() > 0
     223           0 :                 && mygmfwhmcon.size() != nConstraints
     224             :         ) {
     225             :                 log << "If specified, gmfwhmcon must have exactly "
     226             :                         << nConstraints << " elements, even if some are zero"
     227           0 :                         << LogIO::EXCEPTION;
     228             :         }
     229           2 :         uInt compNumber = 0;
     230           4 :         for (uInt i=0; i<mygmncomps.size(); i++) {
     231           2 :                 if (mygmncomps[i] < 0) {
     232             :                         log << "All elements of gmncomps must be positive"
     233           0 :                                 << LogIO::EXCEPTION;
     234             :                 }
     235           2 :                 vector<GaussianSpectralElement> g(mygmncomps[i]);
     236           2 :                 Matrix<Double> constraints(mygmncomps[i] - 1, 3);
     237           8 :                 for (uInt j=0; j<(uInt)mygmncomps[i]; j++) {
     238          18 :                         g[j] = GaussianSpectralElement(
     239           6 :                                 gmampest[compNumber], gmcenterest[compNumber],
     240           6 :                                 GaussianSpectralElement::sigmaFromFWHM(gmfwhmest[compNumber])
     241           6 :                         );
     242           6 :                         if (mygmfix.size() > 0) {
     243           0 :                                 g[j].fixByString(mygmfix[compNumber]);
     244             :                         }
     245           6 :                         if (j > 0) {
     246           4 :                                 constraints(j-1, 0) = mygmampcon[compNumber - (i+1)];
     247           4 :                                 constraints(j-1, 1) = mygmcentercon[compNumber - (i+1)];
     248           4 :                                 constraints(j-1, 2) = mygmfwhmcon[compNumber - (i+1)];
     249             :                         }
     250           6 :                         compNumber++;
     251             :                 }
     252           2 :                 if (
     253           2 :                         ! spectralList.add(
     254           4 :                                 GaussianMultipletSpectralElement(g, constraints)
     255             :                         )
     256             :                 ) {
     257             :                         log << "Unable to add gaussian multiplet to spectral list"
     258           0 :                                 << LogIO::EXCEPTION;
     259             :                 }
     260           2 :         }
     261           2 : }
     262             : 
     263          11 : void SpectralListFactory::_addPowerLogPolynomial(
     264             :         SpectralList& spectralList,
     265             :         LogIO& log, vector<double>& myplpest,
     266             :         vector<bool>& myplpfix
     267             : ) {
     268          11 :         uInt nest = myplpest.size();
     269          11 :         if (nest < 2) {
     270             :                 log << "Number of elements in the power log polynomial estimates list must be at least 2"
     271           0 :                         << LogIO::EXCEPTION;
     272             :         }
     273          11 :         uInt nfix = myplpfix.size();
     274          11 :         if (nfix == 0) {
     275           9 :                 myplpfix = vector<bool>(nest, false);
     276             :         }
     277           2 :         else if (nfix != myplpest.size()) {
     278             :                 log << "Number of elements in the power logarithmic polynomial fixed parameter list must "
     279             :                         << "either be 0 or equal to the number of elements in the estimates list"
     280           0 :                         << LogIO::EXCEPTION;
     281             :         }
     282          11 :     Vector<double> const myplpestV(myplpest);
     283          11 :     Vector<bool> const myplpfixV(myplpfix);
     284          11 :         PowerLogPolynomialSpectralElement plp(myplpestV);
     285          11 :         plp.fix(myplpfixV);
     286          11 :         spectralList.add(plp);
     287          11 : }
     288             : 
     289           5 : void SpectralListFactory::_addLogTransformedPolynomial(
     290             :         SpectralList& spectralList,
     291             :         vector<double>& myltpest,
     292             :         vector<bool>& myltpfix
     293             : ) {
     294           5 :         uInt nest = myltpest.size();
     295           5 :         ThrowIf(
     296             :                 nest < 2,
     297             :                 "Number of elements in the log transformed polynomial "
     298             :                 "estimates list must be at least 2"
     299             :         );
     300           5 :         uInt nfix = myltpfix.size();
     301           5 :         if (nfix == 0) {
     302           4 :                 myltpfix = vector<bool>(nest, false);
     303             :         }
     304             :         else {
     305           1 :                 ThrowIf(
     306             :                         nfix != myltpest.size(),
     307             :                         "Number of elements in the logarithmic transformed polynomial "
     308             :                         "fixed parameter list must either be 0 or equal to the number "
     309             :                         "of elements in the estimates list"
     310             :                 );
     311             :         }
     312           5 :     Vector<double> const myltpestV(myltpest);
     313           5 :     Vector<bool> const myltpfixV(myltpfix);
     314           5 :         LogTransformedPolynomialSpectralElement ltp(myltpestV);
     315           5 :         ltp.fix(myltpfixV);
     316           5 :         spectralList.add(ltp);
     317           5 : }
     318             : 
     319             : using namespace casacore;
     320             : } // end namespace casa

Generated by: LCOV version 1.16