LCOV - code coverage report
Current view: top level - spectrallines/Splatalogue - SplatalogueTable.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 123 181 68.0 %
Date: 2024-12-11 20:54:31 Functions: 6 12 50.0 %

          Line data    Source code
       1             : //# MSContinuumSubtractor.cc:  Subtract continuum from spectral line data
       2             : //# Copyright (C) 2004
       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$
      27             : //#
      28             : 
      29             : #include <spectrallines/Splatalogue/SplatalogueTable.h>
      30             : 
      31             : #include <casacore/casa/Exceptions/Error.h>
      32             : #include <casacore/casa/Quanta/MVTime.h>
      33             : #include <casacore/tables/TaQL/ExprNode.h>
      34             : 
      35             : #include <casacore/tables/Tables/ScaColDesc.h>
      36             : #include <casacore/tables/Tables/ScalarColumn.h>
      37             : #include <iomanip>
      38             : 
      39             : #include <iostream>
      40             : using namespace std;
      41             : 
      42             : using namespace casacore;
      43             : namespace casa {
      44             : 
      45             : const String SplatalogueTable::SPECIES = "SPECIES";
      46             : const String SplatalogueTable::RECOMMENDED = "RECOMMENDED";
      47             : const String SplatalogueTable::CHEMICAL_NAME = "CHEMICAL_NAME";
      48             : const String SplatalogueTable::FREQUENCY = "FREQUENCY";
      49             : const String SplatalogueTable::QUANTUM_NUMBERS = "QUANTUM_NUMBERS";
      50             : const String SplatalogueTable::INTENSITY = "INTENSITY";
      51             : const String SplatalogueTable::SMU2 = "SMU2";
      52             : const String SplatalogueTable::LOGA = "LOGA";
      53             : const String SplatalogueTable::EL = "EL";
      54             : const String SplatalogueTable::EU = "EU";
      55             : const String SplatalogueTable::LINELIST = "LINELIST";
      56             : const String SplatalogueTable::ISSPLAT = "isSplat";
      57             : 
      58             : const String SplatalogueTable::RECORD_VALUE = "value";
      59             : const String SplatalogueTable::RECORD_UNIT = "unit";
      60             : const String SplatalogueTable::RECORD_SPECIES = "species";
      61             : const String SplatalogueTable::RECORD_RECOMMENDED = "recommended";
      62             : const String SplatalogueTable::RECORD_CHEMNAME = "chemname";
      63             : const String SplatalogueTable::RECORD_FREQUENCY = "freq";
      64             : const String SplatalogueTable::RECORD_QNS = "qns";
      65             : const String SplatalogueTable::RECORD_INTENSITY = "intensity";
      66             : const String SplatalogueTable::RECORD_SMU2 = "smu2";
      67             : const String SplatalogueTable::RECORD_LOGA = "loga";
      68             : const String SplatalogueTable::RECORD_EL = "el";
      69             : const String SplatalogueTable::RECORD_EU = "eu";
      70             : const String SplatalogueTable::RECORD_LINE_LIST = "linelist";
      71             : 
      72           2 : SplatalogueTable::SplatalogueTable(
      73             :         SetupNewTable& snt, uInt nrow,
      74             :         const String& freqUnit, const String& smu2Unit,
      75             :         const String& elUnit, const String& euUnit  
      76           2 : ) : Table(snt, nrow), _freqUnit(freqUnit), _smu2Unit(smu2Unit),
      77           4 :          _elUnit(elUnit), _euUnit(euUnit) {
      78           2 :         _construct(true);
      79           2 : }
      80             : 
      81          88 : SplatalogueTable::SplatalogueTable(
      82             :         const String& tablename
      83          88 : ) : Table(tablename) {
      84          87 :         _construct(false);
      85          87 : }
      86             : 
      87          58 : SplatalogueTable::SplatalogueTable(
      88             :         const Table& table
      89          58 : ) : Table(table) {
      90          58 :         _construct(false);
      91          58 : }
      92             : 
      93           0 : String SplatalogueTable::getFrequencyUnit() const {
      94           0 :         return _freqUnit;
      95             : }
      96             : 
      97           4 : String SplatalogueTable::list() const {
      98           4 :         ScalarColumn<String> species(*this, SPECIES);
      99           4 :         ScalarColumn<Bool> recommended(*this, RECOMMENDED);
     100           4 :         ScalarColumn<String> chemName(*this, CHEMICAL_NAME);
     101           4 :         ScalarColumn<Double> freq(*this, FREQUENCY);
     102           4 :         ScalarColumn<String> qns(*this, QUANTUM_NUMBERS);
     103           4 :         ScalarColumn<Float> intensity(*this, INTENSITY);
     104           4 :         ScalarColumn<Float> smu2(*this, SMU2);
     105           4 :         ScalarColumn<Float> logA(*this, LOGA);
     106           4 :         ScalarColumn<Float> el(*this, EL);
     107           4 :         ScalarColumn<Float> eu(*this, EU);
     108           4 :         ScalarColumn<String> linelist(*this, LINELIST);
     109             : 
     110             :         char cspecies[15], crec[11], cchemName[21], cfreq[12], cqns[21],
     111             :                 cintensity[10], csmu2[10], clogA[10], cel[10], ceu[10],
     112             :                 clinelist[11];
     113           4 :         ostringstream os;
     114           4 :         String rec;
     115           4 :         os << SPECIES << "       " << RECOMMENDED << "        "
     116           4 :                 << CHEMICAL_NAME << "   " << FREQUENCY << "     "
     117           4 :                 << QUANTUM_NUMBERS << "  " << INTENSITY << "      "
     118           4 :                 << SMU2 << "      " << LOGA << "        "
     119           4 :                 << EL  << "        " << EU << "  " << LINELIST << endl;
     120       23288 :     for (uInt i=0; i<nrow(); i++) {
     121       23284 :         sprintf(cspecies, "%-14.14s", species.asString(i).chars());
     122       23284 :         rec = recommended.asBool(i) ? "*" : " ";
     123       23284 :         sprintf(crec, "%10.10s", rec.chars());
     124       23284 :         sprintf(cchemName, "%-20.20s", chemName.asString(i).chars());
     125       23284 :         sprintf(cfreq, "%11.6f", freq.asdouble(i));
     126       23284 :         sprintf(cqns, "%-20.20s", qns.asString(i).chars());
     127       23284 :         sprintf(cintensity, "%9.5f", intensity.asfloat(i));
     128       23284 :         sprintf(csmu2, "%9.5f", smu2.asfloat(i));
     129       23284 :         sprintf(clogA, "%9.5f", logA.asfloat(i));
     130       23284 :         sprintf(cel, "%9.5f", el.asfloat(i));
     131       23284 :         sprintf(ceu, "%9.5f", eu.asfloat(i));
     132       23284 :         sprintf(clinelist, "%-10.10s", linelist.asString(i).chars());
     133             : 
     134             :         os << cspecies << " " << crec << " " << cchemName
     135             :                 << " " << cfreq << " " << cqns << " " << cintensity
     136             :                 << " " << csmu2 << " " << clogA << " " << cel
     137       23284 :                 << " " << ceu << "  " << clinelist << endl;
     138             :         }
     139          12 :         return os.str();
     140           4 : }
     141             : 
     142             : namespace {
     143             : template <typename T>
     144             : class Kluge {
     145             : 
     146             : // The latest casacore mode changed the signature to the TableExprNode::getColumnTYPE
     147             : // methods.  Since SplatalogueTable::toRecord is the only code that is using them,
     148             : // I've installed a very limited kluge to fix this issue.  FYI: The casacore mod changed
     149             : // the casacore mode now requires an array of row numbers rather than defaulting to all
     150             : // rows(?).  jjacobs 12/17/12
     151             : 
     152             : 
     153             : public:
     154             : 
     155             : typedef Array<T> (TableExprNode::* Extractor) (const RowNumbers& rownrs) const;
     156             : 
     157             : static Array<T>
     158           0 : extract (const TableExprNode & col, Extractor extractor)
     159             : {
     160           0 :   Vector<rownr_t> rownrs (col.nrow());
     161           0 :   indgen (rownrs);
     162             : 
     163           0 :   return ((& col) ->* extractor) (RowNumbers(rownrs));
     164             : 
     165           0 : }
     166             : 
     167             : };
     168             : }
     169             : 
     170           0 : Record SplatalogueTable::toRecord() const {
     171             : 
     172           0 :         Array<String> species = Kluge<String>::extract (col(SPECIES), & TableExprNode::getColumnString);
     173           0 :         Array<Bool> recommended = Kluge<Bool>::extract (col(RECOMMENDED), & TableExprNode::getColumnBool);
     174           0 :         Array<String> chemName = Kluge<String>::extract (col(CHEMICAL_NAME), & TableExprNode::getColumnString);
     175           0 :         Array<Double> freq = Kluge<Double>::extract (col(FREQUENCY), & TableExprNode::getColumnDouble);
     176           0 :         Array<String> qns = Kluge<String>::extract (col(QUANTUM_NUMBERS), & TableExprNode::getColumnString);
     177           0 :         Array<Float> intensity = Kluge<Float>::extract (col(INTENSITY), & TableExprNode::getColumnFloat);
     178           0 :         Array<Float> smu2 = Kluge<Float>::extract (col(SMU2), & TableExprNode::getColumnFloat);
     179           0 :         Array<Float> loga = Kluge<Float>::extract (col(LOGA), & TableExprNode::getColumnFloat);
     180           0 :         Array<Float> el = Kluge<Float>::extract (col(EL), & TableExprNode::getColumnFloat);
     181           0 :         Array<Float> eu = Kluge<Float>::extract (col(EU), & TableExprNode::getColumnFloat);
     182           0 :         Array<String> linelist = Kluge<String>::extract (col(LINELIST), & TableExprNode::getColumnString);
     183             : 
     184             : //      Array<String> species = col(SPECIES).getColumnString();
     185             : //      Array<Bool> recommended = col(RECOMMENDED).getColumnBool();
     186             : //      Array<String> chemName = col(CHEMICAL_NAME).getColumnString();
     187             : //      Array<Double> freq = col(FREQUENCY).getColumnDouble();
     188             : //      Array<String> qns = col(QUANTUM_NUMBERS).getColumnString();
     189             : //      Array<Float> intensity = col(INTENSITY).getColumnFloat();
     190             : //      Array<Float> smu2 = col(SMU2).getColumnFloat();
     191             : //      Array<Float> loga = col(LOGA).getColumnFloat();
     192             : //      Array<Float> el = col(EL).getColumnFloat();
     193             : //      Array<Float> eu = col(EU).getColumnFloat();
     194             : //      Array<String> linelist = col(LINELIST).getColumnString();
     195             : 
     196           0 :         IPosition idx = IPosition(1, 0);
     197           0 :         Record rec;
     198           0 :         Record qFreq;
     199           0 :         qFreq.define(RECORD_VALUE, 0.0);
     200           0 :         qFreq.define(RECORD_UNIT, _freqUnit);
     201           0 :         Record qSmu2;
     202           0 :         qSmu2.define(RECORD_VALUE, 0.0f);
     203             : 
     204           0 :         qSmu2.define(RECORD_UNIT, _smu2Unit);
     205           0 :         Record qel = qSmu2;
     206           0 :         qel.define(RECORD_UNIT, _elUnit);
     207           0 :         Record qeu = qSmu2;
     208           0 :         qeu.define(RECORD_UNIT, _euUnit);
     209           0 :         for (uInt i=0; i<species.size(); i++) {
     210           0 :                 idx[0] = i;
     211           0 :                 Record line;
     212           0 :                 line.define(RECORD_SPECIES, species(idx));
     213           0 :                 line.define(RECORD_RECOMMENDED, recommended(idx));
     214           0 :                 line.define(RECORD_CHEMNAME, chemName(idx));
     215           0 :                 qFreq.define(RECORD_VALUE, freq(idx));
     216           0 :                 line.defineRecord(RECORD_FREQUENCY, qFreq);
     217           0 :                 line.define(RECORD_QNS, qns(idx));
     218           0 :                 line.define(RECORD_INTENSITY, intensity(idx));
     219           0 :                 qSmu2.define(RECORD_VALUE, smu2(idx));
     220           0 :                 line.defineRecord(RECORD_SMU2, qSmu2);
     221           0 :                 line.define(RECORD_LOGA, loga(idx));
     222           0 :                 qel.define(RECORD_VALUE, el(idx));
     223           0 :                 line.defineRecord(RECORD_EL, qel);
     224           0 :                 qeu.define(RECORD_VALUE, eu(idx));
     225           0 :                 line.defineRecord(RECORD_EU, qeu);
     226           0 :                 line.define(RECORD_LINE_LIST, linelist(idx));
     227           0 :                 rec.defineRecord("*" + String::toString(i), line);
     228           0 :         }
     229           0 :         return rec;
     230           0 : }
     231             : 
     232         147 : void SplatalogueTable::_construct(const Bool setup) {
     233         147 :         if (
     234         147 :                 ! setup
     235         292 :                 && (
     236         145 :                         ! keywordSet().isDefined(ISSPLAT)
     237         292 :                         || ! keywordSet().asBool(ISSPLAT)
     238             :                 )
     239             :         ) {
     240           0 :                 throw AipsError("Table is not a splatalogue table");
     241             :         }
     242         147 :         Vector<String> colNames = tableDesc().columnNames();
     243         147 :         Vector<String> reqColNames(11);
     244         147 :         if (colNames.size() != reqColNames.size()) {
     245           0 :                 throw AipsError("Table does not have the required number of columns to be a Splatalogue table");
     246             :         }
     247             : 
     248         147 :         reqColNames[0] = SPECIES;
     249         147 :         reqColNames[1] = RECOMMENDED;
     250         147 :         reqColNames[2] = CHEMICAL_NAME;
     251         147 :         reqColNames[3] = FREQUENCY;
     252         147 :         reqColNames[4] = QUANTUM_NUMBERS;
     253         147 :         reqColNames[5] = INTENSITY;
     254         147 :         reqColNames[6] = SMU2;
     255         147 :         reqColNames[7] = LOGA;
     256         147 :         reqColNames[8] = EL;
     257         147 :         reqColNames[9] = EU;
     258         147 :         reqColNames[10] = LINELIST;
     259        1617 :         for (
     260         294 :                 Vector<String>::const_iterator riter=reqColNames.begin();
     261        1764 :                         riter!=reqColNames.end(); riter++
     262             :         ) {
     263        1617 :                 Bool found = false;
     264        8085 :                 for (
     265        3234 :                         Vector<String>::const_iterator iter=colNames.begin();
     266        9702 :                                 iter!=colNames.end(); iter++
     267             :                         ) {
     268        9702 :                         if (*iter == *riter) {
     269        1617 :                                 found = true;
     270        1617 :                                 break;
     271             :                         }
     272        1617 :                 }
     273        1617 :                 if (! found) {
     274           0 :                         throw AipsError("Column " + *riter + " does not exist in the input table.");
     275             :                 }
     276         147 :         }
     277             :         // TODO also check column data types
     278         147 :         if (setup) {
     279           2 :                 Bool writable = isWritable();
     280           2 :                 if (! writable) {
     281           0 :                         reopenRW();
     282             :                 }
     283           2 :                 _addKeywords();
     284             :         }
     285             :         else {
     286         145 :                 ScalarColumn<Double> freq(*this, FREQUENCY);
     287         145 :                 _freqUnit = freq.keywordSet().asString("Unit");
     288         145 :                 ScalarColumn<Float> smu2(*this, SMU2);
     289         145 :                 _smu2Unit = smu2.keywordSet().asString("Unit");
     290         145 :                 if (_smu2Unit.empty()) {
     291         145 :                         _smu2Unit = "Debye2";
     292             :                 }
     293         145 :                 ScalarColumn<Float> el(*this, EL);
     294         145 :                 _elUnit = el.keywordSet().asString("Unit");
     295         145 :                 if (_elUnit.empty()) {
     296         145 :                         _elUnit = "K";
     297             :                 }
     298         145 :                 ScalarColumn<Float> eu(*this, EU);
     299         145 :                 _euUnit = eu.keywordSet().asString("Unit");
     300         145 :                 if (_euUnit.empty()) {
     301         145 :                         _euUnit = "K";
     302             :                 }
     303         145 :         }
     304         147 : }
     305             : 
     306             : 
     307           2 : void SplatalogueTable::_addKeywords() {
     308           2 :         if (_freqUnit.empty()) {
     309           0 :                 _freqUnit = "GHz";
     310             :         }
     311           2 :         ScalarColumn<Double> freq(*this, FREQUENCY);
     312           2 :         freq.rwKeywordSet().define("Unit", _freqUnit);
     313           2 :         ScalarColumn<Float> smu2(*this, SMU2);
     314           2 :         smu2.rwKeywordSet().define("Unit", _smu2Unit);
     315           2 :         ScalarColumn<Float> el(*this, EL);
     316           2 :         el.rwKeywordSet().define("Unit", _elUnit);
     317           2 :         ScalarColumn<Float> eu(*this, EU);
     318           2 :         eu.rwKeywordSet().define("Unit", _euUnit);
     319           2 :         rwKeywordSet().define(ISSPLAT, true);
     320           2 :         Time now;
     321           2 :         MVTime mv(now);
     322           2 :         mv.setFormat(MVTime::YMD, 3);
     323           2 :         String timeString = mv.string();
     324           2 :         timeString = String(timeString.before(timeString.size() - 1));
     325             :         // These are required by the standard measures loading code.
     326           2 :         rwKeywordSet().define("VS_CREATE", timeString);
     327           2 :         rwKeywordSet().define("VS_DATE", timeString);
     328           2 :         rwKeywordSet().define("VS_VERSION", timeString);
     329           2 :         rwKeywordSet().define("VS_TYPE", "List of spectral lines in Splatalogue format");
     330           2 :         tableInfo().setType("IERS");
     331           2 : }
     332             : 
     333             : } //# NAMESPACE CASA - END
     334             : 

Generated by: LCOV version 1.16