LCOV - code coverage report
Current view: top level - components/ComponentModels - FluxStandard.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 186 247 75.3 %
Date: 2024-11-06 17:42:47 Functions: 11 11 100.0 %

          Line data    Source code
       1             : //# FluxStandard.cc: Implementation of FluxStandard.h
       2             : //# Copyright (C) 1996,1997,1999,2001,2002
       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: FluxStandard.cc 21292 2012-11-28 14:58:19Z gervandiepen $
      27             : //----------------------------------------------------------------------------
      28             : 
      29             : #include <components/ComponentModels/FluxStandard.h>
      30             : //#include <components/ComponentModels/FluxStdsQS.h>
      31             : #include <components/ComponentModels/FluxStdsQS2.h>
      32             : #include <components/ComponentModels/FluxCalc_SS_JPL_Butler.h>
      33             : #include <components/ComponentModels/ComponentType.h>
      34             : #include <components/ComponentModels/ComponentList.h>
      35             : #include <components/ComponentModels/SkyComponent.h>
      36             : #include <components/ComponentModels/ConstantSpectrum.h>
      37             : #include <components/ComponentModels/TabularSpectrum.h>
      38             : #include <components/ComponentModels/PointShape.h>
      39             : #include <components/ComponentModels/DiskShape.h>
      40             : #include <casacore/casa/BasicMath/Math.h>
      41             : #include <casacore/casa/BasicSL/String.h>
      42             : #include <casacore/casa/BasicSL/Constants.h>
      43             : #include <casacore/casa/Logging/LogIO.h>
      44             : #include <casacore/casa/OS/File.h>
      45             : #include <casacore/casa/OS/Path.h>
      46             : #include <casacore/casa/Utilities/CountedPtr.h>
      47             : #include <sstream>
      48             : #include <iomanip>
      49             : #include <casacore/measures/Measures/MDirection.h>
      50             : #include <casacore/measures/Measures/MCDirection.h>
      51             : #include <casacore/measures/Measures/MeasConvert.h>
      52             : #include <casacore/measures/Measures/MEpoch.h>
      53             : #include <casacore/measures/Measures/MFrequency.h>
      54             : #include <casacore/measures/Measures/MeasTable.h>
      55             : 
      56             : using namespace casacore;
      57             : namespace casa { //# NAMESPACE CASA - BEGIN
      58             : 
      59             : //----------------------------------------------------------------------------
      60             : 
      61          36 : FluxStandard::FluxStandard(const FluxStandard::FluxScale scale) : 
      62          36 :   itsFluxScale(scale),
      63          36 :   has_direction_p(false),
      64          36 :   interpmethod_p("")
      65             : {
      66             : // Default constructor
      67             : // Output to private data:
      68             : //    itsFluxScale      FluxStandard::FluxScale     Flux scale (eg. BAARS)
      69             : //
      70          36 : }
      71             : 
      72             : //----------------------------------------------------------------------------
      73             : 
      74          36 : FluxStandard::~FluxStandard()
      75             : {
      76             : // Default destructor
      77             : //
      78          36 : }
      79             : 
      80             : //----------------------------------------------------------------------------
      81             : 
      82          47 : Bool FluxStandard::compute (const String& sourceName, 
      83             :                             const MDirection& sourceDir,
      84             :                             const MFrequency& mfreq,
      85             :                             const MEpoch& mtime,
      86             :                             Flux <Double>& value, Flux <Double>& error)
      87             : {
      88             :   // I refuse to duplicate the monstrosity below to skip a short for loop.
      89          47 :   Vector<Flux<Double> > fluxes(1);
      90          47 :   Vector<Flux<Double> > errors(1);
      91          47 :   Vector<MFrequency> mfreqs(1);
      92             :   
      93          47 :   mfreqs[0] = mfreq;
      94          47 :   Bool success = compute(sourceName, sourceDir, mfreqs, mtime, fluxes, errors);
      95             :   
      96          47 :   value = fluxes[0];
      97          47 :   error = errors[0];
      98          47 :   return success;
      99          47 : }
     100             : 
     101          19 : Bool FluxStandard::compute(const String& sourceName, 
     102             :                            const MDirection& sourceDir,
     103             :                            const Vector<Vector<MFrequency> >& mfreqs,
     104             :                            const MEpoch& mtime,
     105             :                            Vector<Vector<Flux<Double> > >& values,
     106             :                            Vector<Vector<Flux<Double> > >& errors)
     107             : {
     108          19 :   Bool success = true;
     109          19 :   uInt nspws = mfreqs.nelements();
     110             : 
     111          75 :   for(uInt spw = 0; spw < nspws; ++spw)
     112          56 :     success &= compute(sourceName, sourceDir, mfreqs[spw], mtime, values[spw], errors[spw],
     113             :                        spw == 0);
     114             : 
     115          19 :   return success;
     116             : }
     117             : 
     118         103 : Bool FluxStandard::compute(const String& sourceName, 
     119             :                            const MDirection& sourceDir,
     120             :                            const Vector<MFrequency>& mfreqs,
     121             :                            const MEpoch& mtime,
     122             :                            Vector<Flux<Double> >& values,
     123             :                            Vector<Flux<Double> >& errors,
     124             :                            const Bool verbose)
     125             : {
     126             : // Compute the flux density for a specified source at a specified set of
     127             : // frequencies.
     128             : // Inputs:
     129             : //    sourceName  Source name
     130             : //    mfreqs      Desired frequencies
     131             : //    mtime       Desired time 
     132             : // Output:
     133             : //    values      Computed total flux densities
     134             : //    errors      Flux density uncertainties; 0 => not known.
     135             : //    compute     false if sourceName is not recognized
     136             : //                as a standard reference.
     137             : //
     138         206 :   LogIO os(LogOrigin("FluxStandard", "compute"));
     139             : 
     140             :   // There used to be a big
     141             :   // if(string == 'dfa" || string == "bla" || ...)
     142             :   // ...else if...else... 
     143             :   // chain here, with a similar
     144             :   // switch(standard) statement inside each if clause.  Finally, inside each
     145             :   // switch case came the actual calculation, usually a 2nd or 3rd order
     146             :   // polynomial in log(freq).
     147             :   //
     148             :   // This meant that the chain of string comparisons and case selections,
     149             :   // typically more expensive than the actual calculation, was repeated for
     150             :   // each frequency.  It would have been better to do the source and standard
     151             :   // determination at the start, and then do the calculation like
     152             :   // ans = coeffs[std][src][0] + lf * (coeffs[std][src][1] + lf * ...),
     153             :   // but:
     154             :   //   * std and src would naturally be enums, and thus not quite 
     155             :   //     natural indices for an array.
     156             :   //   * The standards do not necessarily use the same set, or number,
     157             :   //     of sources.
     158             :   // Both of those could be gotten around by using a std::map, but then
     159             :   // accessing the coeffs entails a function call.  Also, it ties the
     160             :   // functional form of the standards to a low-order polynomial in
     161             :   // log(freq).
     162             :   //
     163             :   // If a function call will be used anyway, why not use a functor to cache the
     164             :   // (std, src) state?  It is more convenient than adding a loop over
     165             :   // log10(frequency) inside each switch case.
     166             : 
     167             :   //CountedPtr<FluxCalcQS> fluxStdPtr;
     168         103 :   CountedPtr<FluxCalcVQS> fluxStdPtr;
     169         103 :   Bool timeVariable(false);
     170         103 :   if(itsFluxScale == BAARS)
     171           0 :     fluxStdPtr = new NSTDS::FluxStdBaars;
     172         103 :   else if(itsFluxScale == PERLEY_90)
     173           0 :     fluxStdPtr = new NSTDS::FluxStdPerley90;
     174         103 :   else if(itsFluxScale == PERLEY_TAYLOR_95)
     175           0 :     fluxStdPtr = new NSTDS::FluxStdPerleyTaylor95;
     176         103 :   else if(itsFluxScale == PERLEY_TAYLOR_99)
     177           8 :     fluxStdPtr = new NSTDS::FluxStdPerleyTaylor99;
     178          95 :   else if(itsFluxScale == PERLEY_BUTLER_2010)
     179           2 :     fluxStdPtr = new NSTDS::FluxStdPerleyButler2010;
     180          93 :   else if(itsFluxScale == PERLEY_BUTLER_2013) {
     181           6 :     fluxStdPtr = new NSTDS::FluxStdPerleyButler2013;
     182           6 :     timeVariable=true; // to read from the table 
     183           6 :     if (interpmethod_p=="") {
     184           0 :       ostringstream oss;
     185           0 :       oss << "Unset interpmethod. Please set the method first";
     186           0 :       throw(AipsError(String(oss)));
     187           0 :     }
     188             :   }
     189          87 :   else if(itsFluxScale == SCAIFE_HEALD_2012)
     190           0 :     fluxStdPtr = new NSTDS::FluxStdScaifeHeald2012;
     191          87 :   else if(itsFluxScale == STEVENS_REYNOLDS_2016)
     192           0 :     fluxStdPtr = new NSTDS::FluxStdStevensReynolds2016;
     193          87 :   else if(itsFluxScale == PERLEY_BUTLER_2017) {
     194          87 :     fluxStdPtr = new NSTDS::FluxStdPerleyButler2017;
     195          87 :     timeVariable=true; // to read from the table 
     196          87 :     if (interpmethod_p=="") {
     197           0 :       ostringstream oss;
     198           0 :       oss << "Unset interpmethod. Please set the method first";
     199           0 :       throw(AipsError(String(oss)));
     200           0 :     }
     201             :   }
     202             :   else{
     203           0 :     if(verbose)
     204             :       os << LogIO::SEVERE
     205           0 :          << "Flux standard " << standardName(itsFluxScale)
     206             :          << " cannot be used this way.  (Does it require a time?)"
     207           0 :          << LogIO::POST;
     208           0 :     return false;
     209             :   }
     210             :   os << LogIO::DEBUG1
     211         103 :      << "Using flux standard: " << standardName(itsFluxScale)
     212         103 :      << LogIO::POST;
     213             : 
     214             :   // Set the source or fail.
     215             :   // setSource needs J2000 coordinates for source matching by position
     216         103 :   MDirection sourceDirJ2000;
     217         103 :   if (sourceDir.getRefString()!="J2000") {
     218           0 :     MeasFrame frame(mtime);
     219           0 :     MDirection::Ref outref(MDirection::J2000, frame);
     220           0 :     sourceDirJ2000 = MDirection::Convert(sourceDir, outref)(); 
     221           0 :   }
     222             :   else {
     223         103 :     sourceDirJ2000 = sourceDir;
     224             :   }   
     225         103 :   if(!fluxStdPtr->setSource(sourceName,sourceDirJ2000)){
     226           0 :     if(verbose)
     227             :       os << LogIO::SEVERE
     228           0 :          << sourceName << " is not recognized by " << standardName(itsFluxScale)
     229           0 :          << LogIO::POST;
     230             :     // TODO?: Look for another standard that does recognize sourceName?
     231           0 :     return false;
     232             :   }
     233             :   else{
     234         103 :     direction_p = fluxStdPtr->getDirection();
     235         103 :     has_direction_p = true;
     236             :   }
     237             :   // Compute the flux density values and their uncertainties, returning whether
     238             :   // or not it worked.
     239         103 :   if (timeVariable) return (*fluxStdPtr)(values,errors,mfreqs,mtime,interpmethod_p);
     240          10 :   return (*fluxStdPtr)(values, errors, mfreqs);
     241         103 : }
     242             : 
     243             : // Like compute, but it also saves a ComponentList for the source to disk
     244             : // and returns the name (sourceName_mfreqGHzmtime.cl), making it suitable for
     245             : // resolved sources.
     246             : // mtime is ignored for nonvariable objects.
     247             : // Solar System objects are typically resolved and variable!
     248             : //
     249             : // Currently each component "list" only has 1 or 0 components.
     250             : //
     251             : // Inputs:
     252             : //    sourceName  const String&              Source name
     253             : //    mfreqs      const Vector<MFrequency>&  Desired frequencies
     254             : //    mtime       const MEpoch&              Desired time
     255             : // Output:
     256             : //    values      Vector<Flux>&              Computed total flux densities
     257             : //    errors      Vector<Flux>&              Flux density errors;
     258             : //                                           (0 => unknown).
     259             : //    clnames     Vector<String>&            Pathnames of the
     260             : //                                           ComponentLists.  "" if no
     261             : //                                           components were made.
     262             : //
     263          20 : Bool FluxStandard::computeCL(const String& sourceName,
     264             :                              const Vector<Vector<MFrequency> >& mfreqs,
     265             :                              const MEpoch& mtime, const MDirection& position,
     266             :                              Vector<Vector<Flux<Double> > >& values,
     267             :                              Vector<Vector<Flux<Double> > >& errors,
     268             :                              Vector<String>& clpaths,
     269             :                              const String& prefix)
     270             : {
     271          40 :   LogIO os(LogOrigin("FluxStandard", "computeCL"));
     272          20 :   uInt nspws = mfreqs.nelements();
     273          20 :   Bool success = false;
     274             : 
     275          20 :   if(itsFluxScale < FluxStandard::HAS_RESOLUTION_INFO){
     276          13 :     if(this->compute(sourceName, position, mfreqs, mtime, values, errors)){
     277             :       // Create a point component with the specified flux density.
     278          13 :       MDirection dummy;
     279          13 :       PointShape point(position.getValue().separation(dummy.getValue()) < 1e-7 &&
     280          26 :                        position.getRef() == dummy.getRef() ? direction_p : position);
     281             : 
     282          61 :       for(uInt spw = 0; spw < nspws; ++spw){
     283          96 :         clpaths[spw] = makeComponentList(sourceName, mfreqs[spw], mtime,
     284          48 :                                          values[spw], point,
     285         144 :                                          prefix + "spw" + String::toString(spw) + "_");
     286             :       }
     287          13 :       success = true;
     288          13 :     }
     289             :   }
     290           7 :   else if(itsFluxScale == FluxStandard::SS_JPL_BUTLER){
     291           7 :     FluxCalc_SS_JPL_Butler ssobj(sourceName, mtime);
     292             :     Double angdiam;
     293             : 
     294          21 :     for(uInt spw = 0; spw < nspws; ++spw){
     295          17 :       ComponentType::Shape cmpshape = ssobj.compute(values[spw], errors[spw], angdiam,
     296             :                                                     mfreqs[spw], spw == 0);
     297             :     
     298          17 :       switch(cmpshape){
     299          14 :       case ComponentType::DISK:
     300             :         {
     301             :           // Create a uniform disk component with the specified flux density.
     302          14 :           MDirection dummy;
     303          14 :           DiskShape disk;
     304             : 
     305             :           // Should we worry about tracking position?
     306          28 :           disk.setRefDirection(position.getValue().separation(dummy.getValue()) < 1e-7 &&
     307          42 :                                position.getRef() == dummy.getRef() ? ssobj.getDirection() :
     308             :                                position);
     309             : 
     310          14 :           disk.setWidthInRad(angdiam, angdiam, 0.0);
     311             : 
     312          28 :           clpaths[spw] = makeComponentList(sourceName, mfreqs[spw], mtime,
     313          14 :                                            values[spw], disk,
     314          42 :                                            prefix + "spw" + String::toString(spw) + "_");
     315          14 :           success = true;
     316          14 :           break;
     317          14 :         }
     318           3 :       default: {
     319           3 :         ostringstream oss;
     320             : 
     321           3 :         oss << ComponentType::name(cmpshape) << " is not a supported component type.";
     322           3 :         throw(AipsError(String(oss)));
     323           3 :       }
     324             :       }
     325             :     }
     326           7 :   }
     327          17 :   return success;
     328          20 : }
     329             : 
     330          11 : void FluxStandard::setInterpMethod(const String& interpmethod)
     331             : {
     332          22 :   LogIO os(LogOrigin("FluxStandard", "setInterpMode"));
     333          11 :   if(interpmethod.contains("nearest")) {
     334          11 :     interpmethod_p = "nearestNeighbour";
     335             :   }
     336           0 :   else if(interpmethod.contains("linear")) {
     337           0 :     interpmethod_p = "linear";
     338             :   }
     339           0 :   else if(interpmethod.contains("cubic")) {
     340           0 :     interpmethod_p = "cubic"; 
     341             :   }
     342           0 :   else if(interpmethod.contains("spline")) {
     343           0 :     interpmethod_p = "spline";
     344             :   }
     345             :   else {
     346           0 :     ostringstream oss;
     347           0 :     oss << interpmethod << " is not a supported interpolation method";
     348           0 :     throw(AipsError(String(oss)));
     349           0 :   }  
     350          11 : }
     351             : 
     352             : 
     353             : 
     354          67 : String FluxStandard::makeComponentList(const String& sourceName,
     355             :                                        const Vector<MFrequency>& mfreqs,
     356             :                                        const MEpoch& mtime,
     357             :                                        const Vector<Flux<Double> >& values,
     358             :                                        const ComponentShape& cmp,
     359             :                                        const String& prefix)
     360             : {
     361         134 :   LogIO os(LogOrigin("FluxStandard", "makeComponentList"));
     362          67 :   uInt nchans = mfreqs.nelements();
     363             : 
     364          67 :   if(nchans > 1){
     365          53 :     Vector<MVFrequency> freqvals(nchans);
     366             : 
     367       33644 :     for(uInt c = 0; c < nchans; ++c)
     368       33591 :       freqvals[c] = mfreqs[c].getValue();
     369             : 
     370          53 :     TabularSpectrum ts(mfreqs[0], freqvals, values, mfreqs[0].getRef());
     371             :           
     372             :     return makeComponentList(sourceName, mfreqs[0], mtime,
     373          53 :                              values[0], cmp, ts, prefix);
     374          53 :   }
     375             :   else{
     376          14 :     ConstantSpectrum cspectrum;
     377             : 
     378             :     return makeComponentList(sourceName, mfreqs[0], mtime,
     379          14 :                              values[0], cmp, cspectrum, prefix);
     380          14 :   }
     381          67 : }
     382             : 
     383          79 : String FluxStandard::makeComponentList(const String& sourceName,
     384             :                                        const MFrequency& mfreq,
     385             :                                        const MEpoch& mtime,
     386             :                                        const Flux<Double>& fluxval,
     387             :                                        const ComponentShape& cmp,
     388             :                                        const SpectralModel& spectrum,
     389             :                                        const String& prefix)
     390             : {
     391         158 :   LogIO os(LogOrigin("FluxStandard", "makeComponentList"));
     392             : 
     393             :   // Make up the ComponentList's pathname.
     394          79 :   ostringstream oss;
     395          79 :   oss << prefix << sourceName << "_" //<< setprecision(1)
     396          79 :       << mfreq.get("GHz").getValue() << "GHz";
     397             :   //  String datetime;  // to nearest minute.
     398          79 :   oss << mtime.get("d").getValue() << "d.cl";
     399          79 :   String clpath(oss);
     400             :   // allow space as a part of the path
     401             :   //uInt nspaces = clpath.gsub(" ", "_");
     402             : 
     403             :   os << LogIO::DEBUG1
     404             :      << "sourceName: " << sourceName
     405         158 :      << "\nmfreq: " << mfreq.get("GHz").getValue() << "GHz"
     406         158 :      << "\nmtime: " << mtime.get("d").getValue() << "d"
     407             :    //  << "\nclpath: " << clpath << " (replaced " << nspaces
     408             :     // << " spaces)"
     409         237 :      << LogIO::POST;
     410             : 
     411             :   // If clpath already exists on disk, assume our work here is done, and don't
     412             :   // try to redo it.  It's not just laziness - it avoids collisions.
     413             :   // This happens when a continuum spw has the same center freq as a spectral
     414             :   // spw that is not being scaled by channel.
     415          79 :   File testExistence(clpath);
     416          79 :   if(!testExistence.isDirectory()){
     417             :     // Create a component list containing cmp, and force a call to its d'tor
     418             :     // using scoping rules.
     419          79 :     ComponentList cl;
     420          79 :     SkyComponent skycomp(fluxval, cmp, spectrum);
     421             :         
     422          79 :     cl.add(skycomp);
     423             :     // Since fluxval is given for mfreq, it should update the reference frequency
     424             :     // set via SpectralIndex (TT)
     425          79 :     Int ncl=cl.nelements();
     426          79 :     Vector<Int> which(1);
     427          79 :     which(0) = ncl-1;
     428         158 :     MVFrequency mvfreq = MVFrequency(mfreq.get("Hz").getValue());
     429          79 :     cl.setRefFrequency(which,mvfreq);
     430          79 :     cl.rename(clpath, Table::New);
     431          79 :   }
     432         158 :   return clpath;
     433          79 : }
     434             : 
     435             : //----------------------------------------------------------------------------
     436             : 
     437          36 : Bool FluxStandard::matchStandard (const String& name, 
     438             :                                   FluxStandard::FluxScale& stdEnum,
     439             :                                   String& stdName)
     440             : {
     441             : // Match an input string to a standard/catalog enum and descriptor
     442             : // Inputs:
     443             : //    name             const String&             Input string
     444             : // Output:
     445             : //    stdEnum          FluxStandard::FluxScale   Matching enum
     446             : //    stdName          String                    Standard descriptor for 
     447             : //                                               the matching enum.
     448             : //    matchStandard    Bool                      true if matched; false
     449             : //                                               if default returned.
     450             : //
     451             :   // Set default enum
     452          36 :   stdEnum = FluxStandard::PERLEY_TAYLOR_99;
     453             :   //  stdEnum = FluxStandard::PERLEY_BUTLER_2010;   // Not yet!
     454             : 
     455             :   // Local lowercase copy of input string
     456          36 :   String lname = name;
     457          36 :   lname.downcase();
     458          36 :   Bool matched = true;
     459             : 
     460             :   // Case input string match of:
     461             :   //
     462             :   // Perley (1990)
     463          94 :   if (lname.contains("perley") && 
     464          58 :       (lname.contains("90") || lname.contains("1990"))) {
     465           0 :     stdEnum = FluxStandard::PERLEY_90;
     466             :   }
     467             :   // Perley-Taylor (1995)
     468          50 :   else if (lname.contains("perley") && lname.contains("taylor") &&
     469          14 :       (lname.contains("95") || lname.contains("1995"))) {
     470           0 :     stdEnum = FluxStandard::PERLEY_TAYLOR_95;
     471             :   }
     472             :   // Perley-Taylor (1999)
     473          43 :   else if (lname.contains("perley") && lname.contains("taylor") &&
     474           7 :       (lname.contains("99") || lname.contains("1999"))) {
     475           7 :     stdEnum = FluxStandard::PERLEY_TAYLOR_99;
     476             :   }
     477             :   // Perley-Butler (2010)
     478          62 :   else if (lname.contains("perley") && lname.contains("butler") &&
     479          33 :       (lname.contains("10") || lname.contains("2010"))) {
     480          11 :     stdEnum = FluxStandard::PERLEY_BUTLER_2010;
     481             :   }
     482             :   // Perley-Butler (2013)
     483          37 :   else if (lname.contains("perley") && lname.contains("butler") &&
     484          19 :       (lname.contains("13") || lname.contains("2013"))) {
     485           3 :     stdEnum = FluxStandard::PERLEY_BUTLER_2013;
     486             :   }
     487             :   // Perley-Butler (2017)
     488          23 :   else if (lname.contains("perley") && lname.contains("butler") &&
     489           8 :       (lname.contains("17") || lname.contains("2017"))) {
     490           8 :     stdEnum = FluxStandard::PERLEY_BUTLER_2017;
     491             :   }
     492             :   // Scaife & Heald (2012)
     493           7 :   else if (lname.contains("scaife") && lname.contains("heald") &&
     494           0 :       (lname.contains("12") || lname.contains("2012"))) {
     495           0 :     stdEnum = FluxStandard::SCAIFE_HEALD_2012;
     496             :   }
     497             :   // Stevens-Reynolds (2016)
     498           7 :   else if (lname.contains("stevens") && lname.contains("reynolds") &&
     499           0 :         (lname.contains("16") || lname.contains("2016"))) {
     500           0 :     stdEnum = FluxStandard::STEVENS_REYNOLDS_2016;
     501             :   }
     502             :   // Baars
     503           7 :   else if (lname.contains("baars")) {
     504           0 :     stdEnum = FluxStandard::BAARS;
     505             :   }
     506           7 :   else if(lname.contains("jpl") || lname.contains("horizons")){
     507           7 :     stdEnum = FluxStandard::SS_JPL_BUTLER;
     508             :   }
     509             :   else
     510           0 :     matched = false;
     511             : 
     512             :   // Retrieve standard descriptor
     513          36 :   stdName = standardName (stdEnum);
     514             : 
     515          36 :   return matched;
     516          36 : }
     517             : 
     518             : //----------------------------------------------------------------------------
     519             : 
     520         139 : String FluxStandard::standardName (const FluxStandard::FluxScale& stdEnum)
     521             : {
     522             : // Return the standard descriptor for a specified standard/catalog enum
     523             : // Inputs:
     524             : //    stdEnum          FluxStandard::FluxScale   Standard/catalog enum
     525             : // Output:
     526             : //    standardName     String                    Standard descriptor
     527             : //
     528             :   // Case scale enum of:
     529             :   //
     530         139 :   String stdName;
     531         139 :   switch (stdEnum) {
     532           0 :   case BAARS: {
     533           0 :     stdName = "Baars";
     534           0 :     break;
     535             :   }
     536           0 :   case PERLEY_90: {
     537           0 :     stdName = "Perley 90";
     538           0 :     break;
     539             :   }
     540           0 :   case PERLEY_TAYLOR_95: {
     541           0 :     stdName = "Perley-Taylor 95";
     542           0 :     break;
     543             :   }
     544          15 :   case PERLEY_TAYLOR_99: {
     545          15 :     stdName = "Perley-Taylor 99";
     546          15 :     break;
     547             :   }
     548          13 :   case PERLEY_BUTLER_2010: {
     549          13 :     stdName = "Perley-Butler 2010";
     550          13 :     break;
     551             :   }
     552           9 :   case PERLEY_BUTLER_2013: {
     553           9 :     stdName = "Perley-Butler 2013";
     554           9 :     break;
     555             :   }
     556           0 :     case SCAIFE_HEALD_2012: {
     557           0 :     stdName = "Scaife-Heald 2012";
     558           0 :     break;
     559             :   }
     560          95 :   case PERLEY_BUTLER_2017: {
     561          95 :     stdName = "Perley-Butler 2017";
     562          95 :     break;
     563             :   }
     564           0 :     case STEVENS_REYNOLDS_2016: {
     565           0 :     stdName = "Stevens-Reynolds 2016";
     566           0 :     break;
     567             :   }
     568           7 :   case SS_JPL_BUTLER: 
     569             :     {
     570           7 :       stdName = "JPL-Butler Solar System Object";
     571           7 :       break;
     572             :     }
     573           0 :   default: 
     574             :     {
     575           0 :       stdName = "unrecognized standard";
     576             :     }
     577             :   }
     578         139 :   return stdName;
     579           0 : }
     580             : 
     581             : //----------------------------------------------------------------------------
     582             : // End of FluxStandard definition.
     583             : //----------------------------------------------------------------------------
     584             : 
     585             : } //# NAMESPACE CASA - END
     586             : 

Generated by: LCOV version 1.16