LCOV - code coverage report
Current view: top level - components/ComponentModels - ComponentList.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 60 741 8.1 %
Date: 2023-11-02 14:27:30 Functions: 8 53 15.1 %

          Line data    Source code
       1             : //# ComponentList.cc:  this defines the ComponentList implementation
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,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: aips2-request@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: ComponentList.cc 21229 2012-04-02 12:00:20Z gervandiepen $
      27             : 
      28             : #include <components/ComponentModels/ComponentList.h>
      29             : #include <components/ComponentModels/ComponentType.h>
      30             : #include <components/ComponentModels/Flux.h>
      31             : #include <casacore/tables/Tables/ScalarColumn.h>
      32             : #include <casacore/tables/Tables/ScaColDesc.h>
      33             : #include <casacore/tables/Tables/ScaRecordColDesc.h>
      34             : #include <components/ComponentModels/ComponentShape.h>
      35             : #include <components/ComponentModels/SpectralModel.h>
      36             : #include <casacore/measures/TableMeasures/ScalarMeasColumn.h>
      37             : #include <casacore/measures/TableMeasures/ArrayQuantColumn.h>
      38             : #include <casacore/measures/TableMeasures/ScalarQuantColumn.h>
      39             : #include <casacore/measures/TableMeasures/TableMeasDesc.h>
      40             : #include <casacore/measures/TableMeasures/TableMeasRefDesc.h>
      41             : #include <casacore/measures/TableMeasures/TableMeasValueDesc.h>
      42             : #include <casacore/measures/TableMeasures/TableQuantumDesc.h>
      43             : #include <casacore/casa/Arrays/Array.h>
      44             : #include <casacore/casa/Arrays/ArrayMath.h>
      45             : #include <casacore/casa/Arrays/ArrayLogical.h>
      46             : #include <casacore/casa/Arrays/Vector.h>
      47             : #include <casacore/casa/Arrays/Cube.h>
      48             : #include <casacore/casa/Exceptions/Error.h>
      49             : #include <casacore/casa/Logging/LogIO.h>
      50             : #include <casacore/casa/BasicSL/Constants.h>
      51             : #include <casacore/casa/BasicSL/Complex.h>
      52             : #include <casacore/casa/BasicMath/Math.h>
      53             : #include <casacore/measures/Measures/MDirection.h>
      54             : #include <casacore/measures/Measures/MFrequency.h>
      55             : #include <casacore/measures/Measures/MCDirection.h>
      56             : #include <casacore/measures/Measures/MCFrequency.h>
      57             : #include <casacore/casa/Quanta/MVFrequency.h>
      58             : #include <casacore/casa/Quanta/MVAngle.h>
      59             : #include <casacore/casa/Quanta/MVDirection.h>
      60             : #include <casacore/measures/Measures/MeasConvert.h>
      61             : #include <casacore/casa/Quanta/Quantum.h>
      62             : #include <casacore/casa/Quanta/Unit.h>
      63             : #include <casacore/casa/OS/Path.h>
      64             : #include <casacore/tables/Tables/ArrColDesc.h>
      65             : #include <casacore/tables/Tables/ArrayColumn.h>
      66             : #include <casacore/tables/Tables/ColumnDesc.h>
      67             : #include <casacore/tables/Tables/ScaColDesc.h>
      68             : #include <casacore/tables/Tables/ScalarColumn.h>
      69             : #include <casacore/tables/Tables/SetupNewTab.h>
      70             : #include <casacore/tables/Tables/TableDesc.h>
      71             : #include <casacore/tables/Tables/ColDescSet.h>
      72             : #include <casacore/tables/Tables/TableLock.h>
      73             : #include <casacore/tables/Tables/TableRecord.h>
      74             : #include <casacore/tables/DataMan/TiledCellStMan.h>
      75             : #include <casacore/casa/Utilities/Assert.h>
      76             : #include <casacore/casa/Utilities/GenSort.h>
      77             : #include <casacore/casa/Utilities/Sort.h>
      78             : #include <casacore/casa/BasicSL/String.h>
      79             : #include <casacore/casa/Containers/Record.h>
      80             : 
      81             : using namespace casacore;
      82             : namespace casa { //# NAMESPACE CASA - BEGIN
      83             : 
      84             : const String fluxName = "Flux";
      85             : const String fluxUnitName = "Flux_Unit";
      86             : const String fluxPolName = "Flux_Polarisation";
      87             : const String fluxErrName = "Flux_Error";
      88             : const String shapeName = "Shape";
      89             : const String refDirName = "Reference_Direction";
      90             : const String dirErrName = "Direction_Error";
      91             : const String dirErrUnitName = "Direction_Error_Units";
      92             : const String shapeParName = "Shape_Parameters";
      93             : const String shapeErrName = "Shape_Error";
      94             : const String spectrumName = "Spectrum_Shape";
      95             : const String refFreqName = "Reference_Frequency";
      96             : const String freqErrName = "Frequency_Error";
      97             : const String spectralRecordName = "Spectral_Record";
      98             : const String freqErrUnitName = "Frequency_Error_Units";
      99             : const String spectParName = "Spectral_Parameters";
     100             : const String spectErrName = "Spectral_Error";
     101             : const String labelName = "Label";
     102             : const String optParColName = "Optional_Parameters";
     103             : 
     104             : 
     105         201 : ComponentList::ComponentList()
     106             :   :itsList(),
     107             :    itsNelements(0),
     108             :    itsTable(),
     109             :    itsROFlag(false),
     110             :    itsSelectedFlags(),
     111             :    itsOrder(),
     112             :    itsAddOptCol(false),
     113         201 :    itsRewriteTable(True)
     114             : {
     115         201 :   AlwaysAssert(ok(), AipsError);
     116         201 : }
     117             : 
     118           0 : ComponentList::ComponentList(const Path& fileName, Bool readOnly, Bool rewriteTable)
     119             :   :itsList(),
     120             :    itsNelements(0),
     121             :    itsTable(),
     122             :    itsROFlag(false),
     123             :    itsSelectedFlags(),
     124             :    itsOrder(),
     125             :    itsAddOptCol(false),
     126           0 :    itsRewriteTable(rewriteTable)
     127             : {
     128           0 :   readTable(fileName, readOnly);
     129           0 :   AlwaysAssert(ok(), AipsError);
     130           0 : }
     131             : 
     132           0 : ComponentList::ComponentList(const ComponentList& other)
     133           0 :   :itsList(other.itsList),
     134           0 :    itsNelements(other.itsNelements),
     135           0 :    itsTable(other.itsTable),  
     136           0 :    itsROFlag(other.itsROFlag),
     137           0 :    itsSelectedFlags(other.itsSelectedFlags),
     138           0 :    itsOrder(other.itsOrder),
     139           0 :    itsAddOptCol(other.itsAddOptCol),
     140           0 :    itsRewriteTable(other.itsRewriteTable)
     141             : {
     142           0 :   DebugAssert(ok(), AipsError);
     143           0 : }
     144             : 
     145         200 : ComponentList::~ComponentList() {
     146         200 :   if (! itsROFlag && ! itsTable.isNull() && itsRewriteTable) {
     147           0 :     writeTable();
     148             :   }
     149         200 :   AlwaysAssert(ok(), AipsError);
     150         200 : }
     151             : 
     152           0 : ComponentList& ComponentList::operator=(const ComponentList& other){
     153           0 :   if (this != &other) {
     154           0 :     if (! itsROFlag && ! itsTable.isNull() && itsRewriteTable) {
     155           0 :       writeTable();
     156             :     }
     157           0 :     itsList = other.itsList;
     158           0 :     itsNelements = other.itsNelements;
     159           0 :     itsTable = other.itsTable;
     160           0 :     itsROFlag = other.itsROFlag;
     161           0 :     itsSelectedFlags = other.itsSelectedFlags;
     162           0 :     itsOrder = other.itsOrder;
     163           0 :     itsAddOptCol = other.itsAddOptCol;
     164           0 :     itsRewriteTable = other.itsRewriteTable;
     165             :   }
     166           0 :   DebugAssert(ok(), AipsError);
     167           0 :   return *this;
     168             : }
     169             : 
     170           0 : Bool ComponentList::isPhysical(const Vector<Int>& indices) const {
     171           0 :   DebugAssert(ok(), AipsError);
     172             : // The static_casts are a workaround for an SGI compiler bug
     173           0 :   DebugAssert(allGE(static_cast<const Vector<Int> &>(indices), 0), AipsError);
     174           0 :   DebugAssert(allLT(static_cast<const Vector<Int> &>(indices), 
     175             :                     static_cast<Int>(nelements())), AipsError);
     176           0 :   Bool retVal = true;
     177           0 :   uInt c = indices.nelements();
     178           0 :   while (retVal && c > 0) {
     179           0 :     c--;
     180           0 :     retVal = itsList[indices(c)].isPhysical();
     181             :   }
     182           0 :   return retVal;
     183             : }
     184             : 
     185           0 : Flux<Double> ComponentList::sample(const MDirection& sampleDir,
     186             :                                    const MVAngle& pixelLatSize,
     187             :                                    const MVAngle& pixelLongSize,
     188             :                                    const MFrequency& centerFreq) const {
     189           0 :   DebugAssert(ok(), AipsError);
     190           0 :   const Unit retUnit("Jy");
     191           0 :   const ComponentType::Polarisation retPol(ComponentType::STOKES);
     192           0 :   Vector<DComplex> result(4, DComplex(0,0));
     193           0 :   Flux<Double> compFlux;
     194           0 :   for (uInt i = 0; i < nelements(); i++) {
     195           0 :     compFlux = component(i).sample(sampleDir, pixelLatSize, pixelLongSize,
     196           0 :                                    centerFreq);
     197           0 :     compFlux.convertUnit(retUnit);
     198           0 :     compFlux.convertPol(retPol);
     199           0 :     result += compFlux.value();
     200             :   }
     201           0 :   return Flux<Double>(result, retPol);
     202             : }
     203             : 
     204           0 : void ComponentList::sample(Cube<Double>& samples,
     205             :                            const Unit& reqUnit,
     206             :                            const Vector<MVDirection>& directions, 
     207             :                            const MeasRef<MDirection>& dirRef, 
     208             :                            const MVAngle& pixelLatSize, 
     209             :                            const MVAngle& pixelLongSize, 
     210             :                            const Vector<MVFrequency>& frequencies,
     211             :                            const MeasRef<MFrequency>& freqRef) const {
     212           0 :   samples = 0.0;
     213           0 :   for (uInt i = 0; i < nelements(); i++) {
     214           0 :     component(i).sample(samples, reqUnit, directions, dirRef,
     215           0 :                         pixelLatSize, pixelLongSize, frequencies, freqRef);
     216             :   }
     217           0 : }
     218             : 
     219         201 : void ComponentList::add(SkyComponent component) {
     220             : //  AlwaysAssert(itsROFlag == false, AipsError);
     221         201 :   DebugAssert(ok(), AipsError);
     222         201 :   uInt blockSize = itsList.nelements();
     223         201 :   if (itsNelements == blockSize) {
     224         201 :     const uInt newSize 
     225         201 :       = (blockSize < 50) ? 2 * blockSize + 1 : blockSize + 100;
     226         201 :     itsList.resize(newSize);
     227         201 :     itsSelectedFlags.resize(newSize);
     228         201 :     itsOrder.resize(newSize);
     229             :   }
     230             :   // for limb-darkened disk shape, add an optional col 
     231         201 :   if (component.shape().type()==ComponentType::LDISK) {
     232           0 :     itsAddOptCol=true;
     233             :   }
     234         201 :   itsList[itsNelements] = component;
     235         201 :   itsSelectedFlags[itsNelements] = false;
     236         201 :   itsOrder[itsNelements] = itsNelements;
     237         201 :   itsNelements++;
     238         201 : }
     239             : 
     240           0 : void ComponentList::addList(const ComponentList& list) {
     241           0 :         for (uInt i=0; i<list.nelements(); i++) {
     242           0 :                 add(list.component(i));
     243             :         }
     244           0 : }
     245             : 
     246             : 
     247           0 : void ComponentList::remove(const uInt& index) {
     248             : //  AlwaysAssert(itsROFlag == false, AipsError);
     249           0 :   AlwaysAssert(index < nelements(), AipsError);
     250           0 :   DebugAssert(ok(), AipsError);
     251           0 :   uInt realIndex = itsOrder[index];
     252           0 :   itsSelectedFlags.remove(realIndex, false);
     253           0 :   itsList.remove(realIndex, false);
     254           0 :   itsOrder.remove(index, false);
     255           0 :   itsNelements--;
     256           0 :   for (uInt i = 0; i < nelements(); i++) {
     257           0 :     if (itsOrder[i] > realIndex) {
     258           0 :       itsOrder[i]--;
     259             :     }
     260             :   }
     261           0 : }
     262             : 
     263           0 : void ComponentList::remove(const Vector<Int>& indices) {
     264           0 :   Vector<Int> zeroCheck(indices);
     265           0 :   AlwaysAssert(allGE(zeroCheck, 0), AipsError);
     266           0 :   uInt c = indices.nelements();
     267           0 :   Vector<uInt> uIndices(c);
     268           0 :   convertArray(uIndices, indices);
     269           0 :   GenSort<uInt>::sort(uIndices);
     270           0 :   while (c != 0) {
     271           0 :     c--;
     272           0 :     remove(uIndices(c));
     273             :   }
     274           0 : }
     275             : 
     276        1000 : uInt ComponentList::nelements() const {
     277        1000 :   return itsNelements;
     278             : }
     279             : 
     280           0 : uInt ComponentList::size() const {
     281           0 :   return itsNelements;
     282             : }
     283             : 
     284           0 : void ComponentList::deselect(const Vector<Int>& indexes) {
     285           0 :   for (uInt i = 0; i < indexes.nelements(); i++) {
     286           0 :     AlwaysAssert(indexes(i) < Int(nelements()), AipsError);
     287           0 :     AlwaysAssert(indexes(i) >= 0, AipsError);
     288           0 :     itsSelectedFlags[itsOrder[indexes(i)]] = false;
     289             :   }
     290           0 :   DebugAssert(ok(), AipsError);
     291           0 : }
     292             : 
     293           0 : void ComponentList::select(const Vector<Int>& indexes) {
     294           0 :   for (uInt i = 0; i < indexes.nelements(); i++) {
     295           0 :     AlwaysAssert(indexes(i) < Int(nelements()), AipsError);
     296           0 :     AlwaysAssert(indexes(i) >= 0, AipsError);
     297           0 :     itsSelectedFlags[itsOrder[indexes(i)]] = true;
     298             :   }
     299           0 :   DebugAssert(ok(), AipsError);
     300           0 : }
     301             : 
     302           0 : Vector<Int> ComponentList::selected() const {
     303           0 :   DebugAssert(ok(), AipsError);
     304           0 :   uInt nSelected = 0;
     305           0 :   for (uInt i = 0; i < nelements(); i++) {
     306           0 :     if (itsSelectedFlags[i] == true) {
     307           0 :       nSelected++;
     308             :     }
     309             :   }
     310           0 :   Vector<Int> retVal(nSelected);
     311           0 :   uInt s = 0;
     312           0 :   for (uInt j = 0; j < nelements(); j++) {
     313           0 :     if (itsSelectedFlags[j] == true) {
     314           0 :       retVal(s) = j;
     315           0 :       s++;
     316             :     }
     317             :   }
     318           0 :   return retVal;
     319             : }
     320             : 
     321           0 : void ComponentList::setLabel(const Vector<Int>& which,
     322             :                              const String& newLabel) {
     323             :   uInt c;
     324           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     325           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     326           0 :     c = which(i);
     327           0 :     component(c).label() = newLabel;
     328             :   }
     329           0 :   DebugAssert(ok(), AipsError);
     330           0 : }
     331             : 
     332           0 : void ComponentList::getFlux(Vector<Quantity>& fluxQuant, const Int& which) const {
     333           0 :    SkyComponent comp = component(which);
     334             :    // each element in the returned vector represents a different polarization.
     335             :    // NumericTraits::Conjugate is just a confusing way of saying Complex if you
     336             :    // look at how comp.flux().value() is implemented.
     337           0 :    Vector<Complex> flux(comp.flux().value().nelements());
     338           0 :    convertArray(flux,comp.flux().value());
     339           0 :    Unit unit = comp.flux().unit();
     340           0 :    fluxQuant.resize(flux.nelements());
     341           0 :    for (uInt i=0; i<flux.nelements(); ++i) {
     342           0 :        fluxQuant[i] = Quantity(real(flux[i]), unit);
     343             :    }
     344           0 : }
     345             : 
     346           0 : void ComponentList::getFlux(Vector<Quantum<Complex> >& fluxQuant, const Int& which) {
     347           0 :    SkyComponent comp = component(which);
     348           0 :    Vector<Complex> flux(comp.flux().value().nelements());
     349           0 :    convertArray(flux,comp.flux().value());
     350           0 :    Unit unit = comp.flux().unit();
     351           0 :    fluxQuant.resize(flux.nelements());
     352           0 :    for (uInt i=0; i<flux.nelements(); ++i) {
     353           0 :        fluxQuant[i] = Quantum<Complex>(flux[i], unit);
     354             :    }
     355           0 : }
     356             : 
     357             :    
     358             : 
     359           0 : void ComponentList::setFlux(const Vector<Int>& which,
     360             :                             const Flux<Double>& newFlux) {
     361             :   uInt c;
     362           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     363           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     364           0 :     c = which(i);
     365           0 :     component(c).flux() = newFlux;
     366             :   }
     367           0 :   DebugAssert(ok(), AipsError);
     368           0 : }
     369             : 
     370           0 : Vector<String> ComponentList::getStokes(const Int& which) const {
     371           0 :     SkyComponent comp = component(which);
     372           0 :     ComponentType::Polarisation stokesType = comp.flux().pol();
     373           0 :     Vector<String> polarization(4);
     374             :     // the polarization determination logic needs to be refactored into
     375             :     // a method in a more appropriate class
     376           0 :     if (stokesType == ComponentType::STOKES) {
     377           0 :         polarization[0] = "I";
     378           0 :         polarization[1] = "Q";
     379           0 :         polarization[2] = "U";
     380           0 :         polarization[3] = "V";
     381             :     }
     382           0 :     else if (stokesType == ComponentType::LINEAR) {
     383           0 :         polarization[0] = "XX";
     384           0 :         polarization[1] = "XY";
     385           0 :         polarization[2] = "YX";
     386           0 :         polarization[3] = "YY";
     387             :     }
     388           0 :     else if (stokesType == ComponentType::CIRCULAR) {
     389           0 :         polarization[0] = "RR";
     390           0 :         polarization[1] = "RL";
     391           0 :         polarization[2] = "LR";
     392           0 :         polarization[3] = "LL";
     393             :     }
     394             :     else {
     395           0 :         polarization.set("UNKNOWN");
     396             :     }
     397           0 :     return polarization;
     398             : }
     399             : 
     400           0 : void ComponentList::convertFluxUnit(const Vector<Int>& which,
     401             :                                     const Unit& unit) {
     402             :   uInt c;
     403           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     404           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     405           0 :     c = which(i);
     406           0 :     component(c).flux().convertUnit(unit);
     407             :   }
     408           0 :   DebugAssert(ok(), AipsError);
     409           0 : }
     410             :   
     411           0 : void ComponentList::convertFluxPol(const Vector<Int>& which,
     412             :                                    ComponentType::Polarisation pol) {
     413             :   uInt c;
     414           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     415           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     416           0 :     c = which(i);
     417           0 :     component(c).flux().convertPol(pol);
     418             :   }
     419           0 :   DebugAssert(ok(), AipsError);
     420           0 : }
     421             :  
     422           0 : void ComponentList::setRefDirection(const Vector<Int>& which,
     423             :                                     const MVDirection& newDir) {
     424             :   uInt c;
     425           0 :   MDirection curDir;
     426           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     427           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     428           0 :     c = which(i);
     429           0 :     ComponentShape& curShape = component(c).shape();
     430           0 :     curDir = curShape.refDirection();
     431           0 :     curDir.set(newDir);
     432           0 :     curShape.setRefDirection(curDir);
     433             :   }
     434           0 :   DebugAssert(ok(), AipsError);
     435           0 : }
     436             : 
     437           0 : void ComponentList::setRefDirectionFrame(const Vector<Int>& which,
     438             :                                          MDirection::Types newFrame) {
     439             :   uInt c;
     440           0 :   MDirection curDir;
     441           0 :   const MDirection::Ref newRef(newFrame);
     442           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     443           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     444           0 :     c = which(i);
     445           0 :     ComponentShape& curShape = component(c).shape();
     446           0 :     curDir = curShape.refDirection();
     447           0 :     curDir.set(newRef);
     448           0 :     curShape.setRefDirection(curDir);
     449             :   }
     450           0 :   DebugAssert(ok(), AipsError);
     451           0 : }
     452             : 
     453           0 : void ComponentList::convertRefDirection(const Vector<Int>& which,
     454             :                                         MDirection::Types newFrame) {
     455             :   uInt c;
     456           0 :   MDirection::Convert converter;
     457           0 :   converter.setOut(newFrame);
     458           0 :   MDirection curDir;
     459           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     460           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     461           0 :     c = which(i);
     462           0 :     ComponentShape& curShape = component(c).shape();
     463           0 :     curDir = curShape.refDirection();
     464           0 :     curShape.setRefDirection(converter(curDir));
     465             :   }
     466           0 :   DebugAssert(ok(), AipsError);
     467           0 : }
     468             : 
     469           0 : MDirection ComponentList::getRefDirection(Int which) const {
     470           0 :     const ComponentShape& compShape = component(which).shape();
     471           0 :     MDirection refDir = compShape.refDirection();
     472           0 :     return refDir;
     473             : }
     474             : 
     475           0 : void ComponentList::setShape(const Vector<Int>& which,
     476             :                              const ComponentShape& newShape) {
     477             :   uInt c;
     478           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     479           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     480           0 :     c = which(i);
     481           0 :     component(c).setShape(newShape);
     482             :     //for limb-darkened disk shape
     483           0 :     if (newShape.type()==ComponentType::LDISK) {
     484           0 :       itsAddOptCol=true;
     485             :     }
     486             :   }
     487           0 :   DebugAssert(ok(), AipsError);
     488           0 : }
     489             : 
     490           0 : const ComponentShape* ComponentList::getShape(Int which) const {
     491           0 :     return component(which).shape().getPtr();
     492             : }
     493             : 
     494             : 
     495           0 : void ComponentList::setShapeParms(const Vector<Int>& which,
     496             :                                   const ComponentShape& newShape) {
     497             :   uInt c;
     498           0 :   MDirection oldDir;
     499           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     500           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     501           0 :     c = which(i);
     502           0 :     SkyComponent& comp = component(c);
     503           0 :     oldDir = comp.shape().refDirection();
     504           0 :     component(c).setShape(newShape);
     505           0 :     comp.shape().setRefDirection(oldDir);
     506             :   }
     507           0 :   DebugAssert(ok(), AipsError);
     508           0 : }
     509             : 
     510           0 : void ComponentList::setOptParms(const Vector<Int>& which,
     511             :                                 const ComponentShape& newShape) {
     512             :   uInt c;
     513           0 :   Vector<Double> optparms;
     514           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     515           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     516           0 :     c = which(i);
     517           0 :     SkyComponent& comp = component(c);
     518           0 :     component(c).setShape(newShape);
     519           0 :     if (comp.shape().type()==ComponentType::LDISK) {
     520           0 :       optparms = comp.shape().optParameters(); 
     521             :       //comp.shape().setOptParameters(optparms);
     522           0 :       component(c).optionalParameters()=optparms;
     523           0 :       itsAddOptCol=true;
     524             :     }
     525             :   }
     526           0 :   DebugAssert(ok(), AipsError);
     527           0 : }
     528             : 
     529           0 : void ComponentList::setSpectrum(const Vector<Int>& which,
     530             :                                 const SpectralModel& newSpectrum) {
     531             :   uInt c;
     532           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     533           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     534           0 :     c = which(i);
     535           0 :     component(c).setSpectrum(newSpectrum);
     536             :   }
     537           0 :   DebugAssert(ok(), AipsError);
     538           0 : }
     539             : 
     540           0 : void ComponentList::setSpectrumParms(const Vector<Int>& which,
     541             :                                      const SpectralModel& newSpectrum) {
     542             :   uInt c;
     543           0 :   MFrequency oldFreq;
     544           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     545           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     546           0 :     c = which(i);
     547           0 :     SkyComponent& comp = component(c);
     548           0 :     oldFreq = comp.spectrum().refFrequency();
     549           0 :     component(c).setSpectrum(newSpectrum);
     550           0 :     comp.spectrum().setRefFrequency(oldFreq);
     551             :   }
     552           0 :   DebugAssert(ok(), AipsError);
     553           0 : }
     554             : 
     555           0 : void ComponentList::setRefFrequency(const Vector<Int>& which, 
     556             :                                     const MVFrequency& newFreq) {
     557             :   uInt c;
     558           0 :   MFrequency curFreq;
     559           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     560           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     561           0 :     c = which(i);
     562           0 :     SpectralModel& curSpectrum = component(c).spectrum();
     563           0 :     curFreq = curSpectrum.refFrequency();
     564           0 :     curFreq.set(newFreq);
     565           0 :     curSpectrum.setRefFrequency(curFreq);
     566             :   }
     567           0 :   DebugAssert(ok(), AipsError);
     568           0 : }
     569             : 
     570           0 : void ComponentList::setRefFrequencyFrame(const Vector<Int>& which,
     571             :                                          MFrequency::Types newFrame) {
     572             :   uInt c;
     573           0 :   MFrequency curFreq;
     574           0 :   const MFrequency::Ref newRef(newFrame);
     575           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     576           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     577           0 :     c = which(i);
     578           0 :     SpectralModel& curSpectrum = component(c).spectrum();
     579           0 :     curFreq = curSpectrum.refFrequency();
     580           0 :     curFreq.set(newRef);
     581           0 :     curSpectrum.setRefFrequency(curFreq);
     582             :   }
     583           0 :   DebugAssert(ok(), AipsError);
     584           0 : }
     585             : 
     586             : 
     587           0 : void ComponentList::setRefFrequencyUnit(const Vector<Int>& which,
     588             :                                         const Unit& unit) {
     589             :   uInt c;
     590           0 :   for (uInt i = 0; i < which.nelements(); i++) {
     591           0 :     AlwaysAssert(which(i) >= 0, AipsError);
     592           0 :     c = which(i);
     593           0 :     component(c).spectrum().convertFrequencyUnit(unit);
     594             :   }
     595           0 :   DebugAssert(ok(), AipsError);
     596           0 : }
     597             : 
     598           0 : SkyComponent& ComponentList::component(const uInt& index) {
     599             : //  AlwaysAssert(itsROFlag == false, AipsError);
     600           0 :   AlwaysAssert(index < nelements(), AipsError);
     601           0 :   DebugAssert(ok(), AipsError);
     602           0 :   return itsList[itsOrder[index]];
     603             : }
     604             : 
     605         600 : const SkyComponent& ComponentList::component(const uInt& index) const {
     606         600 :   DebugAssert(ok(), AipsError);
     607         600 :   AlwaysAssert(index < nelements(), AipsError);
     608         600 :   return itsList[itsOrder[index]];
     609             : }
     610             : 
     611           0 : void ComponentList::rename(const Path& fileName, 
     612             :                            const Table::TableOption option) {
     613           0 :   AlwaysAssert(option != Table::Old, AipsError);
     614           0 :   AlwaysAssert(itsROFlag == false, AipsError);
     615           0 :   DebugAssert(ok(), AipsError);
     616           0 :   if (fileName.length() != 0) {
     617             :     // See if this list is associated with a Table. 
     618           0 :     if (itsTable.isNull()) {
     619             :       //createTable(fileName, option, addOptCol_p);
     620           0 :       createTable(fileName, option);
     621             :     } else {
     622           0 :       if (!itsTable.isWritable()) itsTable.reopenRW();
     623           0 :       itsTable.rename(fileName.absoluteName(), option);
     624             :     }
     625             : 
     626             :     // Ensure that the Table::isReadable(fileName) returns true, otherwise the
     627             :     // ok() function will fail.
     628           0 :     itsTable.flush();
     629           0 :     DebugAssert(ok(), AipsError);
     630             :   } else {
     631           0 :     if (!itsTable.isNull()) {
     632           0 :       itsTable.markForDelete();
     633           0 :       itsTable = Table();
     634           0 :       itsROFlag = false;
     635             :     }
     636             :   }
     637           0 : }
     638             : 
     639           0 : ComponentList ComponentList::copy() const {
     640           0 :   DebugAssert(ok(), AipsError);
     641           0 :   ComponentList copiedList;
     642           0 :   SkyComponent currentComp;
     643           0 :   for (uInt c = 0; c < nelements(); c++) {
     644           0 :     currentComp = component(c).copy();
     645           0 :     copiedList.add(currentComp);
     646             :   }
     647           0 :   return copiedList;
     648             : }
     649             : 
     650           0 : void ComponentList::sort(ComponentList::SortCriteria criteria) {
     651           0 :   Block<Double> val(nelements());
     652           0 :   Sort::Order order = Sort::Ascending;
     653           0 :   Bool doSort = true;
     654           0 :   switch (criteria) {
     655           0 :   case ComponentList::FLUX: {
     656           0 :     for (uInt i = 0; i < nelements(); i++) {
     657           0 :       itsList[i].flux().convertPol(ComponentType::STOKES);
     658           0 :       val[i] = abs(itsList[i].flux().value(0u).real());
     659             :     }
     660           0 :     order = Sort::Descending;
     661           0 :     break;
     662             :   }
     663           0 :   case ComponentList::POSITION: {
     664           0 :     MDirection compDir;
     665           0 :     MVDirection refDir(0.0, 0.0);
     666           0 :     Vector<Double> position(2);
     667           0 :     for (uInt i = 0; i < nelements(); i++) {
     668           0 :       val[i] = refDir.separation(itsList[i].shape().refDirection().getValue());
     669             :     }
     670           0 :     order = Sort::Ascending;
     671           0 :     break;
     672             :   }
     673           0 :   case ComponentList::POLARISATION: {
     674           0 :     Vector<Double> f(4);
     675           0 :     for (uInt i = 0; i < nelements(); i++) {
     676           0 :       itsList[i].flux().value(f);
     677           0 :       if (!nearAbs(f(0), 0.0, DBL_MIN)) {
     678           0 :         val[i] = sqrt(f(1)*f(1)+f(2)*f(2)+f(3)*f(3))/f(0);
     679             :       }
     680             :       else {
     681           0 :         val[i] = 0.0;
     682             :       }
     683             :     }
     684           0 :     order = Sort::Descending;
     685           0 :     break;
     686             :   }
     687           0 :   case ComponentList::UNSORTED: 
     688             :   case ComponentList::NUMBER_CRITERIA:
     689           0 :     doSort = false;
     690           0 :     break;
     691             :   };
     692             :   // The genSort function requires a Vector<uInt> and not a Block<uInt> so
     693             :   // I'll create a temporary Vector here which references the data in the
     694             :   // 'itsOrder' Block.
     695           0 :   if (doSort) {
     696           0 :     Vector<uInt> vecOrder(IPosition(1,nelements()), itsOrder.storage(), SHARE);
     697           0 :     AlwaysAssert(genSort(vecOrder, val, order) == nelements(), 
     698             :                  AipsError);
     699             :   }
     700           0 : }
     701             : 
     702           0 : String ComponentList::name(ComponentList::SortCriteria enumerator) {
     703           0 :   switch (enumerator) {
     704           0 :   case ComponentList::FLUX: return "Flux";
     705           0 :   case ComponentList::POSITION: return "Position";
     706           0 :   case ComponentList::POLARISATION: return "Polarization";
     707           0 :   default: return "unknown";
     708             :   };
     709             : }
     710             : 
     711           0 : ComponentList::SortCriteria ComponentList::type(const String& criteria) {
     712           0 :   String canonicalCase(criteria);
     713           0 :   canonicalCase.capitalize();
     714           0 :   for (uInt i = 0; i < ComponentList::NUMBER_CRITERIA; i++) {
     715           0 :     if (canonicalCase.
     716           0 :         matches(ComponentList::name((ComponentList::SortCriteria) i))) {
     717           0 :       return (ComponentList::SortCriteria) i;
     718             :     }
     719             :   }
     720           0 :   return ComponentList::UNSORTED;
     721             : }
     722             : 
     723        1202 : Bool ComponentList::ok() const {
     724             :   // The LogIO class is only constructed if an Error is detected for
     725             :   // performance reasons. Both function static and file static variables
     726             :   // where considered and rejected for this purpose.
     727        1202 :   if (itsList.nelements() < itsNelements) {
     728           0 :     LogIO logErr(LogOrigin("ComponentList", "ok()"));
     729             :     logErr << LogIO::SEVERE 
     730             :            << "The list size is inconsistant with its cached size"
     731           0 :            << LogIO::POST;
     732           0 :      return false;
     733             :   }
     734        1202 :   if (itsROFlag == true && itsTable.isNull() == true) {
     735           0 :     LogIO logErr(LogOrigin("ComponentList", "ok()"));
     736             :     logErr << LogIO::SEVERE 
     737             :            << "Only ComponentList's associated with a Table can be readonly"
     738           0 :            << LogIO::POST;
     739           0 :      return false;
     740             :   }
     741        1202 :   if (itsTable.isNull() == false) {
     742           0 :     String tablename = itsTable.tableName();
     743           0 :     if (Table::isReadable(tablename) == false) {
     744           0 :         LogIO logErr(LogOrigin("ComponentList", "ok()"));
     745             :         logErr << LogIO::SEVERE 
     746             :                << "Table associated with ComponentList is not readable"
     747           0 :                << LogIO::POST;
     748           0 :         return false;
     749             :     }
     750           0 :     if (itsROFlag == false && Table::isWritable(tablename) == false) {
     751           0 :         LogIO logErr(LogOrigin("ComponentList", "ok()"));
     752             :         logErr << LogIO::SEVERE 
     753             :                << "Table associated with ComponentList is not writeable"
     754           0 :                << LogIO::POST;
     755           0 :         return false;
     756             :     }
     757             :   }
     758        2002 :   for (uInt i = 0; i < itsNelements; i++) {
     759         800 :     if (itsOrder[i] >= itsNelements) {
     760           0 :       LogIO logErr(LogOrigin("ComponentList", "ok()"));
     761             :       logErr << LogIO::SEVERE 
     762             :              << "Cannot index to an element that is outside the list!"
     763           0 :              << LogIO::POST;
     764           0 :       return false;
     765             :     }
     766             :   }
     767        1202 :   return true;
     768             : }
     769             : 
     770           0 : void ComponentList::createTable(const Path& fileName,
     771             :                                 const Table::TableOption option) {
     772             :         //                      const Table::TableOption option,
     773             :                     //            const Bool addOptCol) {
     774             :   // Build a default table description
     775           0 :   TableDesc td("ComponentListDescription", "4", TableDesc::Scratch);  
     776           0 :   td.comment() = "A description of a component list";
     777             :   {
     778             :     {
     779             :       const ArrayColumnDesc<DComplex> 
     780           0 :         fluxValCol(fluxName, "Flux values", IPosition(1,4),ColumnDesc::Direct);
     781           0 :       td.addColumn(fluxValCol);
     782             :       const ScalarColumnDesc<String>
     783           0 :         fluxUnitCol(fluxUnitName, "Flux units", ColumnDesc::Direct);
     784           0 :       td.addColumn(fluxUnitCol);
     785             :       const ScalarColumnDesc<String> 
     786             :         fluxPolCol(fluxPolName, "Flux polarisation representation", 
     787           0 :                    ColumnDesc::Direct);
     788           0 :       td.addColumn(fluxPolCol);
     789             :       const ArrayColumnDesc<DComplex> 
     790           0 :         fluxErrCol(fluxErrName, "Flux errors", IPosition(1,4), 
     791           0 :                    ColumnDesc::Direct);
     792           0 :       td.addColumn(fluxErrCol);
     793             :     }
     794             :     {
     795             :       const ScalarColumnDesc<String> 
     796           0 :         shapeCol(shapeName, "Shape of the Component", ColumnDesc::Direct);
     797           0 :       td.addColumn(shapeCol);
     798           0 :       const String dirValColName = refDirName;
     799             :       const ArrayColumnDesc<Double> 
     800             :         dirValCol(dirValColName, "Reference direction values",
     801           0 :                   IPosition(1,2), ColumnDesc::Direct);
     802           0 :       td.addColumn(dirValCol);
     803           0 :       const String dirRefColName = "Direction_Frame";
     804             :       const ScalarColumnDesc<String>
     805             :         dirRefCol(dirRefColName, "The reference direction frame", 
     806           0 :                   ColumnDesc::Direct);
     807           0 :       td.addColumn(dirRefCol);
     808             :       {
     809           0 :         const TableMeasRefDesc dirRefTMCol(td, dirRefColName);
     810           0 :         const TableMeasValueDesc dirValTMCol(td, dirValColName);
     811           0 :         TableMeasDesc<MDirection> dirTMCol(dirValTMCol, dirRefTMCol);
     812           0 :         dirTMCol.write(td);
     813             :       }
     814             :       const ArrayColumnDesc<Double>
     815             :         dirErrCol(dirErrName, "Error in the reference direction values",
     816           0 :                   IPosition(1,2), ColumnDesc::Direct);
     817           0 :       td.addColumn(dirErrCol);
     818             :       const ArrayColumnDesc<String>
     819             :         dirErrUnitCol(dirErrUnitName, "Units of the direction error", 
     820           0 :                       IPosition(1,2), ColumnDesc::Direct);
     821           0 :       td.addColumn(dirErrUnitCol);
     822             :       {
     823           0 :         TableQuantumDesc dirErrTMCol(td, dirErrName, dirErrUnitName);
     824           0 :         dirErrTMCol.write(td);
     825             :       }
     826             : 
     827             :       const ArrayColumnDesc<Double> 
     828             :         shapeParmCol(shapeParName,
     829           0 :                      "Parameters specific to the component shape", 1);
     830           0 :       td.addColumn(shapeParmCol);
     831             :       const ArrayColumnDesc<Double> 
     832             :         shapeErrCol(shapeErrName,
     833           0 :                      "Error in the shape parameters", 1);
     834           0 :       td.addColumn(shapeErrCol);
     835             :     }
     836             :     {
     837             :       const ScalarColumnDesc<String>
     838             :         freqShapeCol(spectrumName, "Shape of the spectrum", 
     839           0 :                      ColumnDesc::Direct);
     840           0 :       td.addColumn (freqShapeCol);
     841           0 :       const String freqValColName = refFreqName;
     842             :       const ScalarColumnDesc<Double>
     843             :         freqValCol(freqValColName, "The reference frequency values", 
     844           0 :                    ColumnDesc::Direct);
     845           0 :       td.addColumn(freqValCol);
     846           0 :       const String freqRefColName = "Frequency_Frame";
     847             :       const ScalarColumnDesc<String>
     848             :         freqRefCol(freqRefColName, "The reference frequency frame", 
     849           0 :                    ColumnDesc::Direct);
     850           0 :       td.addColumn(freqRefCol);
     851             :       {
     852           0 :         const TableMeasRefDesc freqRefTMCol(td, freqRefColName);
     853           0 :         const TableMeasValueDesc freqValTMCol(td, freqValColName);
     854           0 :         TableMeasDesc<MFrequency> freqTMCol(freqValTMCol, freqRefTMCol);
     855           0 :         freqTMCol.write(td);
     856             :       }
     857             :       const ScalarColumnDesc<Double> 
     858             :         freqErrCol(freqErrName, "Error in the reference frequency",
     859           0 :                    ColumnDesc::Direct);
     860           0 :       td.addColumn(freqErrCol);
     861             :       const ScalarColumnDesc<String>
     862             :         freqErrUnitCol(freqErrUnitName, "Units of the frequency error", 
     863           0 :                        ColumnDesc::Direct);
     864           0 :       td.addColumn(freqErrUnitCol);
     865             :       {
     866           0 :         TableQuantumDesc freqErrTMCol(td, freqErrName, freqErrUnitName);
     867           0 :         freqErrTMCol.write(td);
     868             :       }
     869             :       const ArrayColumnDesc<Double> 
     870             :         specParmCol(spectParName, 
     871           0 :                     "Parameters specific to the components spectrum", 1);
     872           0 :       td.addColumn(specParmCol);
     873             :       const ArrayColumnDesc<Double> 
     874             :         specErrCol(spectErrName, 
     875           0 :                    "Errors in the spectral parameters", 1);
     876           0 :       td.addColumn(specErrCol);
     877             :     }
     878             :     {
     879             :       const ScalarColumnDesc<String> 
     880             :         labelCol(labelName, "An arbitrary label for the user",
     881           0 :                  ColumnDesc::Direct);
     882           0 :       td.addColumn (labelCol);
     883             :     }
     884             :   }
     885           0 :   if (itsAddOptCol) {
     886             :     const ArrayColumnDesc<Double>
     887           0 :       optParCol(optParColName,"optional parameter column",1,ColumnDesc::Undefined);
     888           0 :     td.addColumn (optParCol);
     889           0 :     td.defineHypercolumn("TiledOptParms",1,stringToVector(optParColName));
     890             :   } 
     891           0 :   SetupNewTable newTable(fileName.absoluteName(), td, option);
     892             : 
     893           0 :   if (itsAddOptCol) {
     894           0 :     TiledCellStMan optcolsm("TiledOptParms",IPosition(1,1));
     895           0 :     newTable.bindColumn(optParColName,optcolsm);
     896             :   }
     897           0 :   itsTable = Table(newTable, TableLock::AutoLocking, nelements(), false);
     898             :   {
     899           0 :     TableInfo& info(itsTable.tableInfo());
     900           0 :     info.setType(TableInfo::type(TableInfo::COMPONENTLIST));
     901           0 :     info.readmeAddLine(String(
     902             :     "This is a ComponentList Table containing parameterised representations"));
     903           0 :     info.readmeAddLine(String("of the sky brightness."));
     904             :   }
     905           0 : }
     906             : 
     907           0 : void ComponentList::writeTable() {
     908           0 :   if (itsTable.isWritable() == false) {
     909           0 :     itsTable.reopenRW();
     910             :   }
     911           0 :   DebugAssert(itsTable.isWritable(), AipsError);
     912             :   {
     913           0 :     const casacore::rownr_t nRows = itsTable.nrow();
     914           0 :     const casacore::rownr_t nelem = nelements();
     915           0 :     if (nRows < nelem) {
     916           0 :       itsTable.addRow(nelem - nRows);
     917           0 :     } else if (nRows > nelem) {
     918           0 :       Vector<casacore::rownr_t> rows(nRows - nelem);
     919           0 :       indgen(rows, nelem);
     920           0 :       itsTable.removeRow(RowNumbers(rows));
     921             :     }
     922             :   }
     923           0 :   ArrayColumn<DComplex> fluxValCol(itsTable, fluxName);
     924           0 :   ScalarColumn<String> fluxUnitCol(itsTable, fluxUnitName);
     925           0 :   ScalarColumn<String> fluxPolCol(itsTable, fluxPolName);
     926           0 :   ScalarColumn<String> shapeCol(itsTable, shapeName);
     927           0 :   MDirection::ScalarColumn dirCol(itsTable, refDirName);
     928           0 :   ArrayColumn<Double> shapeParmCol(itsTable, shapeParName);
     929           0 :   ScalarColumn<String> specShapeCol(itsTable, spectrumName);
     930           0 :   MFrequency::ScalarColumn freqCol(itsTable, refFreqName);
     931           0 :   ArrayColumn<Double> specShapeParmCol(itsTable, spectParName); 
     932           0 :   ScalarColumn<String> labelCol(itsTable, labelName);
     933           0 :   ArrayColumn<DComplex> fluxErrCol;
     934           0 :   ArrayQuantColumn<Double> dirErrCol;
     935           0 :   ArrayColumn<Double> shapeErrCol;
     936           0 :   ScalarQuantColumn<Double> freqErrCol;
     937           0 :   ArrayColumn<Double> spectErrCol;
     938           0 :   ScalarColumn<TableRecord> specRecord;
     939           0 :   ArrayColumn<Double> optParCol;
     940             :   {
     941           0 :     const ColumnDescSet& cds=itsTable.tableDesc().columnDescSet();
     942           0 :     if (!cds.isDefined(spectralRecordName)) {
     943           0 :       itsTable.addColumn(ScalarRecordColumnDesc(spectralRecordName));
     944             :     }
     945           0 :     specRecord.attach(itsTable, spectralRecordName);
     946           0 :     if (!cds.isDefined(fluxErrName)) {
     947             :       itsTable.addColumn
     948           0 :         (ArrayColumnDesc<DComplex>(fluxErrName, "Flux errors", IPosition(1,4), 
     949             :                                    ColumnDesc::Direct));
     950             :     }
     951             :     
     952           0 :     fluxErrCol.attach(itsTable, fluxErrName);
     953           0 :     if (!cds.isDefined(dirErrName)) {
     954             :       itsTable.addColumn
     955           0 :         (ArrayColumnDesc<Double>(dirErrName,
     956             :                                  "Error in the reference direction values",
     957           0 :                                  IPosition(1,2), ColumnDesc::Direct));
     958             :       itsTable.addColumn
     959           0 :         (ArrayColumnDesc<String>(dirErrUnitName,
     960             :                                  "Units of the direction error",
     961           0 :                                  IPosition(1,2), ColumnDesc::Direct));
     962             :       TableQuantumDesc dirErrTMCol(itsTable.tableDesc(), dirErrName,
     963           0 :                                    dirErrUnitName);
     964           0 :       dirErrTMCol.write(itsTable);
     965             :     }
     966           0 :     dirErrCol.attach(itsTable, dirErrName);
     967           0 :     if (!cds.isDefined(shapeErrName)) {
     968             :       itsTable.addColumn
     969           0 :         (ArrayColumnDesc<Double>(shapeErrName,
     970             :                                  "Error in the shape parameters", 1));
     971             :     }
     972           0 :     shapeErrCol.attach(itsTable, shapeErrName);
     973             : 
     974           0 :     if (!cds.isDefined(freqErrName)) {
     975             :       itsTable.addColumn
     976           0 :         (ScalarColumnDesc<Double>(freqErrName, 
     977             :                                   "Error in the reference frequency",
     978             :                                   ColumnDesc::Direct));
     979             :       itsTable.addColumn
     980           0 :         (ScalarColumnDesc<String>(freqErrUnitName,
     981             :                                   "Units of the frequency error", 
     982             :                                   ColumnDesc::Direct));
     983             :       TableQuantumDesc freqErrTMCol(itsTable.tableDesc(), freqErrName,
     984           0 :                                     freqErrUnitName);
     985           0 :       freqErrTMCol.write(itsTable);
     986             :     }
     987           0 :     freqErrCol.attach(itsTable, freqErrName);
     988           0 :     if (!cds.isDefined(spectErrName)) {
     989             :       itsTable.addColumn
     990           0 :         (ArrayColumnDesc<Double>(spectErrName,
     991             :                                  "Error in the spectral parameters", 1));
     992             :     }
     993           0 :     spectErrCol.attach(itsTable, spectErrName);
     994             : 
     995           0 :     if (itsAddOptCol) {
     996           0 :       if (!cds.isDefined(optParColName)) {
     997             :         itsTable.addColumn
     998           0 :           (ArrayColumnDesc<Double>(optParColName,
     999             :                                  "Optional parameters", 1));
    1000             :         //cerr<<"added optional parameter col"<<endl;
    1001             :       }
    1002           0 :       optParCol.attach(itsTable, optParColName); 
    1003             :     }
    1004             :   }
    1005             :   
    1006           0 :   Vector<Quantum<Double> > dirErr(2);
    1007           0 :   for (uInt i = 0; i < nelements(); i++) {
    1008             :     {
    1009           0 :       const Flux<Double>& flux = component(i).flux();
    1010           0 :       fluxValCol.put(i, flux.value());
    1011           0 :       fluxUnitCol.put(i, flux.unit().getName());
    1012           0 :       fluxPolCol.put(i, ComponentType::name(flux.pol()));
    1013           0 :       fluxErrCol.put(i, flux.errors());
    1014             :     }
    1015             :     {
    1016           0 :       const ComponentShape& compShape = component(i).shape();
    1017           0 :       shapeCol.put(i, compShape.ident());
    1018           0 :       dirCol.put(i, compShape.refDirection());
    1019           0 :       if (!dirErrCol.isNull()) {
    1020           0 :         dirErr(0) = compShape.refDirectionErrorLat();
    1021           0 :         dirErr(1) = compShape.refDirectionErrorLong();
    1022           0 :         dirErrCol.put(i, dirErr);
    1023             :       }
    1024           0 :       shapeParmCol.put(i, compShape.parameters());
    1025           0 :       shapeErrCol.put(i, compShape.errors());
    1026             :     }
    1027             :     {
    1028           0 :       const SpectralModel& compSpectrum = component(i).spectrum();
    1029           0 :       specShapeCol.put(i, compSpectrum.ident());
    1030           0 :       TableRecord rec;
    1031           0 :       String err;
    1032           0 :       if(compSpectrum.toRecord(err, rec))
    1033           0 :         specRecord.put(i,rec);
    1034           0 :       freqCol.put(i, compSpectrum.refFrequency());
    1035           0 :       if (!freqErrCol.isNull()) {
    1036           0 :         freqErrCol.put(i, compSpectrum.refFrequencyError());
    1037             :       }
    1038           0 :       specShapeParmCol.put(i, compSpectrum.parameters());
    1039           0 :       spectErrCol.put(i, compSpectrum.errors());
    1040             :     }
    1041             :     {
    1042           0 :       labelCol.put(i, component(i).label());
    1043             :     }
    1044           0 :     if (itsAddOptCol) {
    1045           0 :       const ComponentShape& compShape2 = component(i).shape();
    1046           0 :       if (compShape2.type()==ComponentType::LDISK) { 
    1047             :         //optParCol.put(i,compShape2.optParameters());
    1048           0 :         optParCol.put(i,component(i).optionalParameters());
    1049             :       }
    1050             :     }
    1051             :   }
    1052           0 : }
    1053             : 
    1054           0 : void ComponentList::readTable(const Path& fileName, const Bool readOnly) {
    1055             :   {
    1056           0 :     const String& fullName = fileName.absoluteName();
    1057           0 :     if (readOnly) {
    1058           0 :       AlwaysAssert(Table::isReadable(fullName), AipsError);
    1059           0 :       itsTable = Table(fullName, Table::Old);
    1060             :     }
    1061             :     else {
    1062           0 :       AlwaysAssert(Table::isWritable(fullName), AipsError);
    1063           0 :       itsTable = Table(fullName, TableLock(TableLock::AutoLocking),
    1064           0 :                        Table::Update);
    1065             :     }
    1066             :   }
    1067           0 :   const ArrayColumn<DComplex> fluxValCol(itsTable, fluxName);
    1068           0 :   const ScalarColumn<String> fluxUnitCol(itsTable, fluxUnitName);
    1069           0 :   const ScalarColumn<String> fluxPolCol(itsTable, fluxPolName);
    1070           0 :   const ScalarColumn<String> shapeCol(itsTable, shapeName);
    1071           0 :   const MDirection::ScalarColumn dirCol(itsTable, refDirName);
    1072           0 :   const ArrayColumn<Double> shapeParmCol(itsTable, shapeParName);
    1073           0 :   const ScalarColumn<String> specShapeCol(itsTable, spectrumName);
    1074           0 :   const MFrequency::ScalarColumn freqCol(itsTable, refFreqName);
    1075           0 :   const ArrayColumn<Double> spectralParmCol(itsTable,spectParName); 
    1076           0 :   const ScalarColumn<String> labelCol(itsTable, labelName);
    1077             : 
    1078           0 :   ArrayColumn<DComplex> fluxErrCol;
    1079           0 :   ROArrayQuantColumn<Double> dirErrCol;
    1080           0 :   ArrayColumn<Double> shapeErrCol;
    1081           0 :   ROScalarQuantColumn<Double> freqErrCol;
    1082           0 :   ArrayColumn<Double> spectralErrCol;
    1083           0 :   ScalarColumn<TableRecord> specRecord;
    1084           0 :   ArrayColumn<Double> optParmCol;
    1085             :   {// Old componentlist tables may not have the error columns
    1086           0 :     const ColumnDescSet& cds=itsTable.tableDesc().columnDescSet();
    1087           0 :     if (cds.isDefined(fluxErrName)) {
    1088           0 :       fluxErrCol.attach(itsTable, fluxErrName);
    1089             :     }
    1090           0 :     if (cds.isDefined(dirErrName)) {
    1091           0 :       dirErrCol.attach(itsTable, dirErrName);
    1092             :     }
    1093           0 :     if (cds.isDefined(shapeErrName)) {
    1094           0 :       shapeErrCol.attach(itsTable, shapeErrName);
    1095             :     }
    1096           0 :     if (cds.isDefined(freqErrName)) {
    1097           0 :       freqErrCol.attach(itsTable, freqErrName);
    1098             :     }
    1099           0 :     if (cds.isDefined(spectErrName)) {
    1100           0 :       spectralErrCol.attach(itsTable, spectErrName);
    1101             :     }
    1102           0 :     if (cds.isDefined(spectralRecordName)) {
    1103           0 :       specRecord.attach(itsTable, spectralRecordName);
    1104             :     }
    1105             :     // new optional parameter column
    1106           0 :     if (cds.isDefined(optParColName)) {
    1107           0 :       optParmCol.attach(itsTable,optParColName);
    1108             :     }
    1109             :   }
    1110             : 
    1111           0 :   SkyComponent currentComp;
    1112           0 :   const uInt nComp = fluxValCol.nrow();
    1113           0 :   Vector<DComplex> compFluxValue(4);
    1114           0 :   Vector<Double> shapeParms, spectralParms, optParms;
    1115           0 :   String compName, compLabel, compFluxPol, compFluxUnit, compSpectrum;
    1116           0 :   MDirection compDir;
    1117           0 :   MFrequency compFreq;
    1118           0 :   Vector<Quantum<Double> > newDirErr(2);
    1119           0 :   Quantum<Double> newFreqErr;
    1120           0 :   for (uInt i = 0; i < nComp; i++) {
    1121           0 :     shapeCol.get(i, compName);
    1122           0 :     specShapeCol.get(i, compSpectrum);
    1123             :     //cout << "CompSpec " << compSpectrum << " shape " <<ComponentType::spectralShape(compSpectrum) <<  endl;
    1124           0 :     currentComp = SkyComponent(ComponentType::shape(compName),
    1125           0 :                                ComponentType::spectralShape(compSpectrum));
    1126             :     {
    1127           0 :       Flux<Double>& compFlux = currentComp.flux();
    1128           0 :       fluxValCol.get(i, compFluxValue);
    1129           0 :       compFlux.setValue(compFluxValue);
    1130           0 :       fluxUnitCol.get(i, compFluxUnit); 
    1131           0 :       compFlux.setUnit(compFluxUnit);
    1132           0 :       fluxPolCol.get(i, compFluxPol); 
    1133           0 :       compFlux.setPol(ComponentType::polarisation(compFluxPol));
    1134           0 :       if (!fluxErrCol.isNull()) {
    1135           0 :         fluxErrCol.get(i, compFluxValue);
    1136           0 :         compFlux.setErrors(compFluxValue(0), compFluxValue(1),
    1137           0 :                            compFluxValue(2), compFluxValue(3));
    1138             :       }
    1139             :     }
    1140             :     {
    1141           0 :       ComponentShape& compShape = currentComp.shape();
    1142           0 :       dirCol.get(i, compDir);
    1143           0 :       compShape.setRefDirection(compDir);
    1144           0 :       if (!dirErrCol.isNull()) {
    1145           0 :         dirErrCol.get(i, newDirErr);
    1146           0 :         compShape.setRefDirectionError(newDirErr(0), newDirErr(1));
    1147             :       }
    1148           0 :       shapeParmCol.get(i, shapeParms, true);
    1149           0 :       compShape.setParameters(shapeParms);
    1150           0 :       if (!shapeErrCol.isNull()) {
    1151           0 :         shapeErrCol.get(i, shapeParms);
    1152           0 :         compShape.setErrors(shapeParms);
    1153             :       }
    1154             :     }
    1155             :     {
    1156           0 :       freqCol.get(i, compFreq);
    1157           0 :       SpectralModel& compSpectrum = currentComp.spectrum();
    1158             :       
    1159           0 :       if (!specRecord.isNull()) {
    1160           0 :         if(specRecord.isDefined(i)){
    1161           0 :           TableRecord rec;
    1162           0 :           specRecord.get(i, rec);
    1163           0 :           String err;
    1164           0 :           compSpectrum.fromRecord(err, rec);
    1165             :         }
    1166             :       }
    1167           0 :       compSpectrum.setRefFrequency(compFreq);
    1168           0 :       if (!freqErrCol.isNull()) {
    1169           0 :         freqErrCol.get(i, newFreqErr);
    1170           0 :         compSpectrum.setRefFrequencyError(newFreqErr);
    1171             :       }
    1172           0 :       spectralParmCol.get(i, spectralParms, true);
    1173           0 :       compSpectrum.setParameters(spectralParms);
    1174           0 :       if (!spectralErrCol.isNull()) {
    1175           0 :         spectralErrCol.get(i, spectralParms);
    1176           0 :         compSpectrum.setErrors(spectralParms);
    1177             :       }
    1178             :     }
    1179             :     {
    1180           0 :       labelCol.get(i, currentComp.label());
    1181             :     }
    1182             :     {
    1183           0 :       if (!optParmCol.isNull()) {
    1184           0 :         if (optParmCol.isDefined(i)) {
    1185           0 :           ComponentShape& compShape2 = currentComp.shape();
    1186           0 :           optParmCol.get(i,optParms,true);
    1187           0 :           compShape2.setOptParameters(optParms); 
    1188           0 :           currentComp.optionalParameters()=optParms;
    1189             :         }
    1190             :       }
    1191             :     }
    1192             :   
    1193           0 :     add(currentComp);
    1194             :   }
    1195           0 :   itsROFlag = readOnly;
    1196           0 : }
    1197             : 
    1198         200 : Bool ComponentList::toRecord(String& error, RecordInterface& outRec) const {
    1199             : 
    1200         200 :   Bool retval=true;
    1201             : 
    1202         200 :   outRec.define("nelements", itsNelements);
    1203         400 :   for (uInt k=0; k < itsNelements; ++k){ 
    1204         400 :     Record componentContainer;
    1205         200 :     retval= (retval && component(k).toRecord(error, componentContainer));
    1206         400 :     String componentId=String("component")+String::toString(k);
    1207         200 :     outRec.defineRecord(componentId, componentContainer);
    1208             : 
    1209             :   }
    1210         200 :   return retval;
    1211             : 
    1212             : }
    1213             : 
    1214         200 : Bool ComponentList::fromRecord(String& error, const RecordInterface& inRec){
    1215             : 
    1216         200 :         Bool retval= true;
    1217         200 :         if(itsNelements > 0){
    1218           0 :                 LogIO logErr(LogOrigin("ComponentList", "fromRecord()"));
    1219             :                 logErr << LogIO::SEVERE
    1220             :                 << "Trying to overwrite a non-empty componentList  from Record"
    1221           0 :                 << LogIO::POST;
    1222           0 :                 return false;
    1223             : 
    1224             :         }
    1225             : 
    1226         200 :         uInt nelements=0;
    1227         200 :         if (inRec.isDefined("nelements")) {
    1228         200 :                 inRec.get("nelements", nelements);
    1229         200 :                 if(nelements >0){
    1230         400 :                         for(uInt k=0; k < nelements; ++k){
    1231         400 :                                 String componentId=String("component")+String::toString(k);
    1232         200 :                                 Record componentRecord=inRec.asRecord(componentId);
    1233         200 :                                 SkyComponent  tempComponent;
    1234         200 :                                 retval=(retval && tempComponent.fromRecord(error, componentRecord));
    1235         200 :                                 if(retval){
    1236         200 :                                         add(tempComponent);
    1237             :                                 }
    1238             :                                 else{
    1239           0 :                                         return retval;
    1240             :                                 }
    1241             :                         }
    1242             :                 }
    1243             :         }
    1244         200 :         return retval;
    1245             : }
    1246             : 
    1247           0 : String ComponentList::summarize(uInt index) const {
    1248           0 :           AlwaysAssert(index < nelements(), AipsError);
    1249           0 :           DebugAssert(ok(), AipsError);
    1250           0 :           return component(index).summarize();
    1251             : }
    1252             : 
    1253           0 : Table& ComponentList::_getTable() {
    1254           0 :     return itsTable;
    1255             : }
    1256             : 
    1257           0 : const Table& ComponentList::getTable() const {
    1258           0 :     return itsTable;
    1259             : }
    1260             : 
    1261             : // Local Variables: 
    1262             : // compile-command: "gmake ComponentList"
    1263             : // End: 
    1264             : 
    1265             : } //# NAMESPACE CASA - END
    1266             : 

Generated by: LCOV version 1.16