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