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 25602 : ComponentList::ComponentList()
112 25602 : :itsList(),
113 25602 : itsNelements(0),
114 25602 : itsTable(),
115 25602 : itsROFlag(false),
116 25602 : itsSelectedFlags(),
117 25602 : itsOrder(),
118 25602 : itsAddOptCol(false),
119 25602 : itsRewriteTable(True)
120 : {
121 25602 : AlwaysAssert(ok(), AipsError);
122 25602 : }
123 :
124 0 : ComponentList::ComponentList(const Path& fileName, Bool readOnly, Bool rewriteTable)
125 0 : :itsList(),
126 0 : itsNelements(0),
127 0 : itsTable(),
128 0 : itsROFlag(false),
129 0 : itsSelectedFlags(),
130 0 : itsOrder(),
131 0 : itsAddOptCol(false),
132 0 : itsRewriteTable(rewriteTable)
133 : {
134 0 : readTable(fileName, readOnly);
135 0 : AlwaysAssert(ok(), AipsError);
136 0 : }
137 :
138 0 : ComponentList::ComponentList(const ComponentList& other)
139 0 : :itsList(other.itsList),
140 0 : itsNelements(other.itsNelements),
141 0 : itsTable(other.itsTable),
142 0 : itsROFlag(other.itsROFlag),
143 0 : itsSelectedFlags(other.itsSelectedFlags),
144 0 : itsOrder(other.itsOrder),
145 0 : itsAddOptCol(other.itsAddOptCol),
146 0 : itsRewriteTable(other.itsRewriteTable)
147 : {
148 0 : }
149 :
150 25601 : ComponentList::~ComponentList() {
151 25601 : if (! itsROFlag && ! itsTable.isNull() && itsRewriteTable) {
152 0 : writeTable();
153 : }
154 : // AlwaysAssert(ok(), AipsError);
155 25601 : }
156 :
157 0 : ComponentList& ComponentList::operator=(const ComponentList& other){
158 0 : if (this != &other) {
159 0 : if (! itsROFlag && ! itsTable.isNull() && itsRewriteTable) {
160 0 : writeTable();
161 : }
162 0 : itsList = other.itsList;
163 0 : itsNelements = other.itsNelements;
164 0 : itsTable = other.itsTable;
165 0 : itsROFlag = other.itsROFlag;
166 0 : itsSelectedFlags = other.itsSelectedFlags;
167 0 : itsOrder = other.itsOrder;
168 0 : itsAddOptCol = other.itsAddOptCol;
169 0 : itsRewriteTable = other.itsRewriteTable;
170 : }
171 0 : 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 0 : 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 0 : samples = 0.0;
211 0 : for (uInt i = 0; i < nelements(); i++) {
212 0 : component(i).sample(samples, reqUnit, directions, dirRef,
213 : pixelLatSize, pixelLongSize, frequencies, freqRef);
214 : }
215 0 : }
216 :
217 25602 : void ComponentList::add(SkyComponent component) {
218 : // AlwaysAssert(itsROFlag == false, AipsError);
219 25602 : uInt blockSize = itsList.nelements();
220 25602 : if (itsNelements == blockSize) {
221 25602 : const uInt newSize
222 25602 : = (blockSize < 50) ? 2 * blockSize + 1 : blockSize + 100;
223 25602 : itsList.resize(newSize);
224 25602 : itsSelectedFlags.resize(newSize);
225 25602 : itsOrder.resize(newSize);
226 : }
227 : // for limb-darkened disk shape, add an optional col
228 25602 : if (component.shape().type()==ComponentType::LDISK) {
229 0 : itsAddOptCol=true;
230 : }
231 25602 : itsList[itsNelements] = component;
232 25602 : itsSelectedFlags[itsNelements] = false;
233 25602 : itsOrder[itsNelements] = itsNelements;
234 25602 : itsNelements++;
235 25602 : }
236 :
237 0 : void ComponentList::addList(const ComponentList& list) {
238 0 : for (uInt i=0; i<list.nelements(); i++) {
239 0 : add(list.component(i));
240 : }
241 0 : }
242 :
243 :
244 0 : void ComponentList::remove(const uInt& index) {
245 : // AlwaysAssert(itsROFlag == false, AipsError);
246 0 : AlwaysAssert(index < nelements(), AipsError);
247 0 : uInt realIndex = itsOrder[index];
248 0 : itsSelectedFlags.remove(realIndex, false);
249 0 : itsList.remove(realIndex, false);
250 0 : itsOrder.remove(index, false);
251 0 : itsNelements--;
252 0 : for (uInt i = 0; i < nelements(); i++) {
253 0 : if (itsOrder[i] > realIndex) {
254 0 : itsOrder[i]--;
255 : }
256 : }
257 0 : }
258 :
259 0 : void ComponentList::remove(const Vector<Int>& indices) {
260 0 : Vector<Int> zeroCheck(indices);
261 0 : AlwaysAssert(allGE(zeroCheck, 0), AipsError);
262 0 : uInt c = indices.nelements();
263 0 : Vector<uInt> uIndices(c);
264 0 : convertArray(uIndices, indices);
265 0 : GenSort<uInt>::sort(uIndices);
266 0 : while (c != 0) {
267 0 : c--;
268 0 : remove(uIndices(c));
269 : }
270 0 : }
271 :
272 53600 : uInt ComponentList::nelements() const {
273 53600 : return itsNelements;
274 : }
275 :
276 0 : uInt ComponentList::size() const {
277 0 : 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 0 : void ComponentList::setLabel(const Vector<Int>& which,
315 : const String& newLabel) {
316 : uInt c;
317 0 : for (uInt i = 0; i < which.nelements(); i++) {
318 0 : AlwaysAssert(which(i) >= 0, AipsError);
319 0 : c = which(i);
320 0 : component(c).label() = newLabel;
321 : }
322 0 : }
323 :
324 0 : void ComponentList::getFlux(Vector<casacore::Quantity>& fluxQuant, int which) const {
325 0 : 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 0 : Vector<Complex> flux(comp.flux().value().nelements());
330 0 : convertArray(flux,comp.flux().value());
331 0 : Unit unit = comp.flux().unit();
332 0 : fluxQuant.resize(flux.nelements());
333 0 : for (uInt i=0; i<flux.nelements(); ++i) {
334 0 : fluxQuant[i] = casacore::Quantity(real(flux[i]), unit);
335 : }
336 0 : }
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 0 : void ComponentList::setFlux(const Vector<Int>& which,
352 : const Flux<Double>& newFlux) {
353 : uInt c;
354 0 : for (uInt i = 0; i < which.nelements(); i++) {
355 0 : AlwaysAssert(which(i) >= 0, AipsError);
356 0 : c = which(i);
357 0 : component(c).flux() = newFlux;
358 : }
359 0 : }
360 :
361 0 : Vector<String> ComponentList::getStokes(const Int& which) const {
362 0 : SkyComponent comp = component(which);
363 0 : ComponentType::Polarisation stokesType = comp.flux().pol();
364 0 : Vector<String> polarization(4);
365 : // the polarization determination logic needs to be refactored into
366 : // a method in a more appropriate class
367 0 : if (stokesType == ComponentType::STOKES) {
368 0 : polarization[0] = "I";
369 0 : polarization[1] = "Q";
370 0 : polarization[2] = "U";
371 0 : 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 0 : return polarization;
389 0 : }
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 0 : void ComponentList::setRefDirection(const Vector<Int>& which,
412 : const MVDirection& newDir) {
413 : uInt c;
414 0 : MDirection curDir;
415 0 : for (uInt i = 0; i < which.nelements(); i++) {
416 0 : AlwaysAssert(which(i) >= 0, AipsError);
417 0 : c = which(i);
418 0 : ComponentShape& curShape = component(c).shape();
419 0 : curDir = curShape.refDirection();
420 0 : curDir.set(newDir);
421 0 : curShape.setRefDirection(curDir);
422 : }
423 0 : }
424 :
425 0 : void ComponentList::setRefDirectionFrame(const Vector<Int>& which,
426 : MDirection::Types newFrame) {
427 : uInt c;
428 0 : MDirection curDir;
429 0 : const MDirection::Ref newRef(newFrame);
430 0 : for (uInt i = 0; i < which.nelements(); i++) {
431 0 : AlwaysAssert(which(i) >= 0, AipsError);
432 0 : c = which(i);
433 0 : ComponentShape& curShape = component(c).shape();
434 0 : curDir = curShape.refDirection();
435 0 : curDir.set(newRef);
436 0 : curShape.setRefDirection(curDir);
437 : }
438 0 : }
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 0 : MDirection ComponentList::getRefDirection(Int which) const {
456 0 : const ComponentShape& compShape = component(which).shape();
457 0 : MDirection refDir = compShape.refDirection();
458 0 : return refDir;
459 : }
460 :
461 0 : void ComponentList::setShape(const Vector<Int>& which,
462 : const ComponentShape& newShape) {
463 : uInt c;
464 0 : for (uInt i = 0; i < which.nelements(); i++) {
465 0 : AlwaysAssert(which(i) >= 0, AipsError);
466 0 : c = which(i);
467 0 : component(c).setShape(newShape);
468 : //for limb-darkened disk shape
469 0 : if (newShape.type()==ComponentType::LDISK) {
470 0 : itsAddOptCol=true;
471 : }
472 : }
473 0 : }
474 :
475 0 : const ComponentShape* ComponentList::getShape(Int which) const {
476 0 : return component(which).shape().getPtr();
477 : }
478 :
479 :
480 0 : void ComponentList::setShapeParms(const Vector<Int>& which,
481 : const ComponentShape& newShape) {
482 : uInt c;
483 0 : MDirection oldDir;
484 0 : for (uInt i = 0; i < which.nelements(); i++) {
485 0 : AlwaysAssert(which(i) >= 0, AipsError);
486 0 : c = which(i);
487 0 : SkyComponent& comp = component(c);
488 0 : oldDir = comp.shape().refDirection();
489 0 : component(c).setShape(newShape);
490 0 : comp.shape().setRefDirection(oldDir);
491 : }
492 0 : }
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 0 : void ComponentList::setSpectrumParms(const Vector<Int>& which,
523 : const SpectralModel& newSpectrum) {
524 : uInt c;
525 0 : MFrequency oldFreq;
526 0 : for (uInt i = 0; i < which.nelements(); i++) {
527 0 : AlwaysAssert(which(i) >= 0, AipsError);
528 0 : c = which(i);
529 0 : SkyComponent& comp = component(c);
530 0 : oldFreq = comp.spectrum().refFrequency();
531 0 : component(c).setSpectrum(newSpectrum);
532 0 : comp.spectrum().setRefFrequency(oldFreq);
533 : }
534 0 : }
535 :
536 0 : void ComponentList::setRefFrequency(const Vector<Int>& which,
537 : const MVFrequency& newFreq) {
538 : uInt c;
539 0 : MFrequency curFreq;
540 0 : for (uInt i = 0; i < which.nelements(); i++) {
541 0 : AlwaysAssert(which(i) >= 0, AipsError);
542 0 : c = which(i);
543 0 : SpectralModel& curSpectrum = component(c).spectrum();
544 0 : curFreq = curSpectrum.refFrequency();
545 0 : curFreq.set(newFreq);
546 0 : curSpectrum.setRefFrequency(curFreq);
547 : }
548 0 : }
549 :
550 0 : void ComponentList::setRefFrequencyFrame(const Vector<Int>& which,
551 : MFrequency::Types newFrame) {
552 : uInt c;
553 0 : MFrequency curFreq;
554 0 : const MFrequency::Ref newRef(newFrame);
555 0 : for (uInt i = 0; i < which.nelements(); i++) {
556 0 : AlwaysAssert(which(i) >= 0, AipsError);
557 0 : c = which(i);
558 0 : SpectralModel& curSpectrum = component(c).spectrum();
559 0 : curFreq = curSpectrum.refFrequency();
560 0 : curFreq.set(newRef);
561 0 : curSpectrum.setRefFrequency(curFreq);
562 : }
563 0 : }
564 :
565 :
566 0 : void ComponentList::setRefFrequencyUnit(const Vector<Int>& which,
567 : const Unit& unit) {
568 : uInt c;
569 0 : for (uInt i = 0; i < which.nelements(); i++) {
570 0 : AlwaysAssert(which(i) >= 0, AipsError);
571 0 : c = which(i);
572 0 : component(c).spectrum().convertFrequencyUnit(unit);
573 : }
574 0 : }
575 :
576 0 : SkyComponent& ComponentList::component(const uInt& index) {
577 : // AlwaysAssert(itsROFlag == false, AipsError);
578 0 : AlwaysAssert(index < nelements(), AipsError);
579 0 : return itsList[itsOrder[index]];
580 : }
581 :
582 27200 : const SkyComponent& ComponentList::component(const uInt& index) const {
583 27200 : AlwaysAssert(index < nelements(), AipsError);
584 27200 : return itsList[itsOrder[index]];
585 : }
586 :
587 0 : void ComponentList::rename(const Path& fileName,
588 : const Table::TableOption option) {
589 0 : AlwaysAssert(option != Table::Old, AipsError);
590 0 : AlwaysAssert(itsROFlag == false, AipsError);
591 0 : if (fileName.length() != 0) {
592 : // See if this list is associated with a Table.
593 0 : if (itsTable.isNull()) {
594 : //createTable(fileName, option, addOptCol_p);
595 0 : 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 0 : itsTable.flush();
604 : } else {
605 0 : if (!itsTable.isNull()) {
606 0 : itsTable.markForDelete();
607 0 : itsTable = Table();
608 0 : itsROFlag = false;
609 : }
610 : }
611 0 : }
612 :
613 0 : ComponentList ComponentList::copy() const {
614 0 : ComponentList copiedList;
615 0 : SkyComponent currentComp;
616 0 : for (uInt c = 0; c < nelements(); c++) {
617 0 : currentComp = component(c).copy();
618 0 : copiedList.add(currentComp);
619 : }
620 0 : return copiedList;
621 0 : }
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 25602 : 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 25602 : 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 25602 : 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 25602 : if (! itsTable.isNull()) {
715 0 : String tablename = itsTable.tableName();
716 0 : 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 0 : 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 0 : }
731 25602 : for (uInt i = 0; i < itsNelements; i++) {
732 0 : 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 25602 : return true;
741 : }
742 :
743 0 : 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 0 : TableDesc td("ComponentListDescription", "4", TableDesc::Scratch);
749 0 : td.comment() = "A description of a component list";
750 : {
751 : {
752 : const ArrayColumnDesc<DComplex>
753 0 : fluxValCol(fluxName, "Flux values", IPosition(1,4),ColumnDesc::Direct);
754 0 : td.addColumn(fluxValCol);
755 : const ScalarColumnDesc<String>
756 0 : fluxUnitCol(fluxUnitName, "Flux units", ColumnDesc::Direct);
757 0 : td.addColumn(fluxUnitCol);
758 : const ScalarColumnDesc<String>
759 : fluxPolCol(fluxPolName, "Flux polarisation representation",
760 0 : ColumnDesc::Direct);
761 0 : td.addColumn(fluxPolCol);
762 : const ArrayColumnDesc<DComplex>
763 0 : fluxErrCol(fluxErrName, "Flux errors", IPosition(1,4),
764 0 : ColumnDesc::Direct);
765 0 : td.addColumn(fluxErrCol);
766 0 : }
767 : {
768 : const ScalarColumnDesc<String>
769 0 : shapeCol(shapeName, "Shape of the Component", ColumnDesc::Direct);
770 0 : td.addColumn(shapeCol);
771 0 : const String dirValColName = refDirName;
772 : const ArrayColumnDesc<Double>
773 : dirValCol(dirValColName, "Reference direction values",
774 0 : IPosition(1,2), ColumnDesc::Direct);
775 0 : td.addColumn(dirValCol);
776 0 : const String dirRefColName = "Direction_Frame";
777 : const ScalarColumnDesc<String>
778 : dirRefCol(dirRefColName, "The reference direction frame",
779 0 : ColumnDesc::Direct);
780 0 : td.addColumn(dirRefCol);
781 : {
782 0 : const TableMeasRefDesc dirRefTMCol(td, dirRefColName);
783 0 : const TableMeasValueDesc dirValTMCol(td, dirValColName);
784 0 : TableMeasDesc<MDirection> dirTMCol(dirValTMCol, dirRefTMCol);
785 0 : dirTMCol.write(td);
786 0 : }
787 : const ArrayColumnDesc<Double>
788 : dirErrCol(dirErrName, "Error in the reference direction values",
789 0 : IPosition(1,2), ColumnDesc::Direct);
790 0 : td.addColumn(dirErrCol);
791 : const ArrayColumnDesc<String>
792 : dirErrUnitCol(dirErrUnitName, "Units of the direction error",
793 0 : IPosition(1,2), ColumnDesc::Direct);
794 0 : td.addColumn(dirErrUnitCol);
795 : {
796 0 : TableQuantumDesc dirErrTMCol(td, dirErrName, dirErrUnitName);
797 0 : dirErrTMCol.write(td);
798 0 : }
799 :
800 : const ArrayColumnDesc<Double>
801 : shapeParmCol(shapeParName,
802 0 : "Parameters specific to the component shape", 1);
803 0 : td.addColumn(shapeParmCol);
804 : const ArrayColumnDesc<Double>
805 : shapeErrCol(shapeErrName,
806 0 : "Error in the shape parameters", 1);
807 0 : td.addColumn(shapeErrCol);
808 0 : }
809 : {
810 : const ScalarColumnDesc<String>
811 : freqShapeCol(spectrumName, "Shape of the spectrum",
812 0 : ColumnDesc::Direct);
813 0 : td.addColumn (freqShapeCol);
814 0 : const String freqValColName = refFreqName;
815 : const ScalarColumnDesc<Double>
816 : freqValCol(freqValColName, "The reference frequency values",
817 0 : ColumnDesc::Direct);
818 0 : td.addColumn(freqValCol);
819 0 : const String freqRefColName = "Frequency_Frame";
820 : const ScalarColumnDesc<String>
821 : freqRefCol(freqRefColName, "The reference frequency frame",
822 0 : ColumnDesc::Direct);
823 0 : td.addColumn(freqRefCol);
824 : {
825 0 : const TableMeasRefDesc freqRefTMCol(td, freqRefColName);
826 0 : const TableMeasValueDesc freqValTMCol(td, freqValColName);
827 0 : TableMeasDesc<MFrequency> freqTMCol(freqValTMCol, freqRefTMCol);
828 0 : freqTMCol.write(td);
829 0 : }
830 : const ScalarColumnDesc<Double>
831 : freqErrCol(freqErrName, "Error in the reference frequency",
832 0 : ColumnDesc::Direct);
833 0 : td.addColumn(freqErrCol);
834 : const ScalarColumnDesc<String>
835 : freqErrUnitCol(freqErrUnitName, "Units of the frequency error",
836 0 : ColumnDesc::Direct);
837 0 : td.addColumn(freqErrUnitCol);
838 : {
839 0 : TableQuantumDesc freqErrTMCol(td, freqErrName, freqErrUnitName);
840 0 : freqErrTMCol.write(td);
841 0 : }
842 : const ArrayColumnDesc<Double>
843 : specParmCol(spectParName,
844 0 : "Parameters specific to the components spectrum", 1);
845 0 : td.addColumn(specParmCol);
846 : const ArrayColumnDesc<Double>
847 : specErrCol(spectErrName,
848 0 : "Errors in the spectral parameters", 1);
849 0 : td.addColumn(specErrCol);
850 0 : }
851 : {
852 : const ScalarColumnDesc<String>
853 : labelCol(labelName, "An arbitrary label for the user",
854 0 : ColumnDesc::Direct);
855 0 : td.addColumn (labelCol);
856 0 : }
857 : }
858 0 : 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 0 : SetupNewTable newTable(fileName.absoluteName(), td, option);
865 :
866 0 : if (itsAddOptCol) {
867 0 : TiledCellStMan optcolsm("TiledOptParms",IPosition(1,1));
868 0 : newTable.bindColumn(optParColName,optcolsm);
869 0 : }
870 0 : itsTable = Table(newTable, TableLock::AutoLocking, nelements(), false);
871 : {
872 0 : TableInfo& info(itsTable.tableInfo());
873 0 : info.setType(TableInfo::type(TableInfo::COMPONENTLIST));
874 0 : info.readmeAddLine(String(
875 : "This is a ComponentList Table containing parameterised representations"));
876 0 : info.readmeAddLine(String("of the sky brightness."));
877 : }
878 0 : }
879 :
880 0 : void ComponentList::writeTable() {
881 0 : if (itsTable.isWritable() == false) {
882 0 : itsTable.reopenRW();
883 : }
884 : {
885 0 : const casacore::rownr_t nRows = itsTable.nrow();
886 0 : const casacore::rownr_t nelem = nelements();
887 0 : if (nRows < nelem) {
888 0 : itsTable.addRow(nelem - nRows);
889 0 : } 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 0 : ArrayColumn<DComplex> fluxValCol(itsTable, fluxName);
896 0 : ScalarColumn<String> fluxUnitCol(itsTable, fluxUnitName);
897 0 : ScalarColumn<String> fluxPolCol(itsTable, fluxPolName);
898 0 : ScalarColumn<String> shapeCol(itsTable, shapeName);
899 0 : MDirection::ScalarColumn dirCol(itsTable, refDirName);
900 0 : ArrayColumn<Double> shapeParmCol(itsTable, shapeParName);
901 0 : ScalarColumn<String> specShapeCol(itsTable, spectrumName);
902 0 : MFrequency::ScalarColumn freqCol(itsTable, refFreqName);
903 0 : ArrayColumn<Double> specShapeParmCol(itsTable, spectParName);
904 0 : ScalarColumn<String> labelCol(itsTable, labelName);
905 0 : ArrayColumn<DComplex> fluxErrCol;
906 0 : ArrayQuantColumn<Double> dirErrCol;
907 0 : ArrayColumn<Double> shapeErrCol;
908 0 : ScalarQuantColumn<Double> freqErrCol;
909 0 : ArrayColumn<Double> spectErrCol;
910 0 : ScalarColumn<TableRecord> specRecord;
911 0 : ArrayColumn<Double> optParCol;
912 : {
913 0 : const ColumnDescSet& cds=itsTable.tableDesc().columnDescSet();
914 0 : if (!cds.isDefined(spectralRecordName)) {
915 0 : itsTable.addColumn(ScalarRecordColumnDesc(spectralRecordName));
916 : }
917 0 : specRecord.attach(itsTable, spectralRecordName);
918 0 : if (!cds.isDefined(fluxErrName)) {
919 : itsTable.addColumn
920 0 : (ArrayColumnDesc<DComplex>(fluxErrName, "Flux errors", IPosition(1,4),
921 : ColumnDesc::Direct));
922 : }
923 :
924 0 : fluxErrCol.attach(itsTable, fluxErrName);
925 0 : 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 0 : dirErrCol.attach(itsTable, dirErrName);
939 0 : if (!cds.isDefined(shapeErrName)) {
940 : itsTable.addColumn
941 0 : (ArrayColumnDesc<Double>(shapeErrName,
942 : "Error in the shape parameters", 1));
943 : }
944 0 : shapeErrCol.attach(itsTable, shapeErrName);
945 :
946 0 : 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 0 : freqErrCol.attach(itsTable, freqErrName);
960 0 : if (!cds.isDefined(spectErrName)) {
961 : itsTable.addColumn
962 0 : (ArrayColumnDesc<Double>(spectErrName,
963 : "Error in the spectral parameters", 1));
964 : }
965 0 : spectErrCol.attach(itsTable, spectErrName);
966 :
967 0 : 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 0 : Vector<Quantum<Double> > dirErr(2);
979 0 : for (uInt i = 0; i < nelements(); i++) {
980 : {
981 0 : const Flux<Double>& flux = component(i).flux();
982 0 : fluxValCol.put(i, flux.value());
983 0 : fluxUnitCol.put(i, flux.unit().getName());
984 0 : fluxPolCol.put(i, ComponentType::name(flux.pol()));
985 0 : fluxErrCol.put(i, flux.errors());
986 : }
987 : {
988 0 : const ComponentShape& compShape = component(i).shape();
989 0 : shapeCol.put(i, compShape.ident());
990 0 : dirCol.put(i, compShape.refDirection());
991 0 : if (!dirErrCol.isNull()) {
992 0 : dirErr(0) = compShape.refDirectionErrorLat();
993 0 : dirErr(1) = compShape.refDirectionErrorLong();
994 0 : dirErrCol.put(i, dirErr);
995 : }
996 0 : shapeParmCol.put(i, compShape.parameters());
997 0 : shapeErrCol.put(i, compShape.errors());
998 : }
999 : {
1000 0 : const SpectralModel& compSpectrum = component(i).spectrum();
1001 0 : specShapeCol.put(i, compSpectrum.ident());
1002 0 : TableRecord rec;
1003 0 : String err;
1004 0 : if(compSpectrum.toRecord(err, rec))
1005 0 : specRecord.put(i,rec);
1006 0 : freqCol.put(i, compSpectrum.refFrequency());
1007 0 : if (!freqErrCol.isNull()) {
1008 0 : freqErrCol.put(i, compSpectrum.refFrequencyError());
1009 : }
1010 0 : specShapeParmCol.put(i, compSpectrum.parameters());
1011 0 : spectErrCol.put(i, compSpectrum.errors());
1012 0 : }
1013 : {
1014 0 : labelCol.put(i, component(i).label());
1015 : }
1016 0 : 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 0 : }
1025 :
1026 0 : void ComponentList::readTable(const Path& fileName, const Bool readOnly) {
1027 : {
1028 0 : const String& fullName = fileName.absoluteName();
1029 0 : if (readOnly) {
1030 0 : AlwaysAssert(Table::isReadable(fullName), AipsError);
1031 0 : itsTable = Table(fullName, Table::Old);
1032 : }
1033 : else {
1034 0 : AlwaysAssert(Table::isWritable(fullName), AipsError);
1035 0 : itsTable = Table(fullName, TableLock(TableLock::AutoLocking),
1036 0 : Table::Update);
1037 : }
1038 : }
1039 0 : const ArrayColumn<DComplex> fluxValCol(itsTable, fluxName);
1040 0 : const ScalarColumn<String> fluxUnitCol(itsTable, fluxUnitName);
1041 0 : const ScalarColumn<String> fluxPolCol(itsTable, fluxPolName);
1042 0 : const ScalarColumn<String> shapeCol(itsTable, shapeName);
1043 0 : const MDirection::ScalarColumn dirCol(itsTable, refDirName);
1044 0 : const ArrayColumn<Double> shapeParmCol(itsTable, shapeParName);
1045 0 : const ScalarColumn<String> specShapeCol(itsTable, spectrumName);
1046 0 : const MFrequency::ScalarColumn freqCol(itsTable, refFreqName);
1047 0 : const ArrayColumn<Double> spectralParmCol(itsTable,spectParName);
1048 0 : const ScalarColumn<String> labelCol(itsTable, labelName);
1049 :
1050 0 : ArrayColumn<DComplex> fluxErrCol;
1051 0 : ROArrayQuantColumn<Double> dirErrCol;
1052 0 : ArrayColumn<Double> shapeErrCol;
1053 0 : ROScalarQuantColumn<Double> freqErrCol;
1054 0 : ArrayColumn<Double> spectralErrCol;
1055 0 : ScalarColumn<TableRecord> specRecord;
1056 0 : ArrayColumn<Double> optParmCol;
1057 : {// Old componentlist tables may not have the error columns
1058 0 : const ColumnDescSet& cds=itsTable.tableDesc().columnDescSet();
1059 0 : if (cds.isDefined(fluxErrName)) {
1060 0 : fluxErrCol.attach(itsTable, fluxErrName);
1061 : }
1062 0 : if (cds.isDefined(dirErrName)) {
1063 0 : dirErrCol.attach(itsTable, dirErrName);
1064 : }
1065 0 : if (cds.isDefined(shapeErrName)) {
1066 0 : shapeErrCol.attach(itsTable, shapeErrName);
1067 : }
1068 0 : if (cds.isDefined(freqErrName)) {
1069 0 : freqErrCol.attach(itsTable, freqErrName);
1070 : }
1071 0 : if (cds.isDefined(spectErrName)) {
1072 0 : spectralErrCol.attach(itsTable, spectErrName);
1073 : }
1074 0 : if (cds.isDefined(spectralRecordName)) {
1075 0 : specRecord.attach(itsTable, spectralRecordName);
1076 : }
1077 : // new optional parameter column
1078 0 : if (cds.isDefined(optParColName)) {
1079 0 : optParmCol.attach(itsTable,optParColName);
1080 : }
1081 : }
1082 :
1083 0 : SkyComponent currentComp;
1084 0 : const uInt nComp = fluxValCol.nrow();
1085 0 : Vector<DComplex> compFluxValue(4);
1086 0 : Vector<Double> shapeParms, spectralParms, optParms;
1087 0 : String compName, compLabel, compFluxPol, compFluxUnit, compSpectrum;
1088 0 : MDirection compDir;
1089 0 : MFrequency compFreq;
1090 0 : Vector<Quantum<Double> > newDirErr(2);
1091 0 : Quantum<Double> newFreqErr;
1092 0 : for (uInt i = 0; i < nComp; i++) {
1093 0 : shapeCol.get(i, compName);
1094 0 : specShapeCol.get(i, compSpectrum);
1095 : //cout << "CompSpec " << compSpectrum << " shape " <<ComponentType::spectralShape(compSpectrum) << endl;
1096 0 : currentComp = SkyComponent(ComponentType::shape(compName),
1097 0 : ComponentType::spectralShape(compSpectrum));
1098 : {
1099 0 : Flux<Double>& compFlux = currentComp.flux();
1100 0 : fluxValCol.get(i, compFluxValue);
1101 0 : compFlux.setValue(compFluxValue);
1102 0 : fluxUnitCol.get(i, compFluxUnit);
1103 0 : compFlux.setUnit(compFluxUnit);
1104 0 : fluxPolCol.get(i, compFluxPol);
1105 0 : compFlux.setPol(ComponentType::polarisation(compFluxPol));
1106 0 : if (!fluxErrCol.isNull()) {
1107 0 : fluxErrCol.get(i, compFluxValue);
1108 0 : compFlux.setErrors(compFluxValue(0), compFluxValue(1),
1109 0 : compFluxValue(2), compFluxValue(3));
1110 : }
1111 : }
1112 : {
1113 0 : ComponentShape& compShape = currentComp.shape();
1114 0 : dirCol.get(i, compDir);
1115 0 : compShape.setRefDirection(compDir);
1116 0 : if (!dirErrCol.isNull()) {
1117 0 : dirErrCol.get(i, newDirErr);
1118 0 : compShape.setRefDirectionError(newDirErr(0), newDirErr(1));
1119 : }
1120 0 : shapeParmCol.get(i, shapeParms, true);
1121 0 : compShape.setParameters(shapeParms);
1122 0 : if (!shapeErrCol.isNull()) {
1123 0 : shapeErrCol.get(i, shapeParms);
1124 0 : compShape.setErrors(shapeParms);
1125 : }
1126 : }
1127 : {
1128 0 : freqCol.get(i, compFreq);
1129 0 : SpectralModel& compSpectrum = currentComp.spectrum();
1130 :
1131 0 : if (!specRecord.isNull()) {
1132 0 : if(specRecord.isDefined(i)){
1133 0 : TableRecord rec;
1134 0 : specRecord.get(i, rec);
1135 0 : String err;
1136 0 : compSpectrum.fromRecord(err, rec);
1137 0 : }
1138 : }
1139 0 : compSpectrum.setRefFrequency(compFreq);
1140 0 : if (!freqErrCol.isNull()) {
1141 0 : freqErrCol.get(i, newFreqErr);
1142 0 : compSpectrum.setRefFrequencyError(newFreqErr);
1143 : }
1144 0 : spectralParmCol.get(i, spectralParms, true);
1145 0 : compSpectrum.setParameters(spectralParms);
1146 0 : if (!spectralErrCol.isNull()) {
1147 0 : spectralErrCol.get(i, spectralParms);
1148 0 : compSpectrum.setErrors(spectralParms);
1149 : }
1150 : }
1151 : {
1152 0 : labelCol.get(i, currentComp.label());
1153 : }
1154 : {
1155 0 : 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 0 : add(currentComp);
1166 : }
1167 0 : itsROFlag = readOnly;
1168 0 : }
1169 :
1170 800 : Bool ComponentList::toRecord(String& error, RecordInterface& outRec) const {
1171 :
1172 800 : Bool retval=true;
1173 :
1174 800 : outRec.define("nelements", itsNelements);
1175 1600 : for (uInt k=0; k < itsNelements; ++k){
1176 800 : Record componentContainer;
1177 800 : retval= (retval && component(k).toRecord(error, componentContainer));
1178 1600 : String componentId=String("component")+String::toString(k);
1179 800 : outRec.defineRecord(componentId, componentContainer);
1180 :
1181 800 : }
1182 800 : return retval;
1183 :
1184 : }
1185 :
1186 25600 : Bool ComponentList::fromRecord(String& error, const RecordInterface& inRec){
1187 :
1188 25600 : Bool retval= true;
1189 25600 : 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 25600 : uInt nelements=0;
1199 25600 : if (inRec.isDefined("nelements")) {
1200 25600 : inRec.get("nelements", nelements);
1201 25600 : if(nelements >0){
1202 51200 : for(uInt k=0; k < nelements; ++k){
1203 51200 : String componentId=String("component")+String::toString(k);
1204 25600 : Record componentRecord=inRec.asRecord(componentId);
1205 25600 : SkyComponent tempComponent;
1206 25600 : retval=(retval && tempComponent.fromRecord(error, componentRecord));
1207 25600 : if(retval){
1208 25600 : add(tempComponent);
1209 : }
1210 : else{
1211 0 : return retval;
1212 : }
1213 25600 : }
1214 : }
1215 : }
1216 25600 : 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 0 : Table& ComponentList::_getTable() {
1225 0 : return itsTable;
1226 : }
1227 :
1228 0 : const Table& ComponentList::getTable() const {
1229 0 : 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 0 : void ComponentList::putKeyword(const String& keyword, const variant& value) {
1238 0 : ThrowIf(itsTable.isNull(), "A table is not attached to this ComponentList");
1239 0 : if (! itsTable.isWritable()) {
1240 0 : itsTable.reopenRW();
1241 : }
1242 0 : std::unique_ptr<ValueHolder> aval(toValueHolder(value));
1243 0 : TableProxy tp(itsTable);
1244 0 : tp.putKeyword(String(), keyword, -1, false, *aval);
1245 0 : }
1246 :
1247 0 : variant* ComponentList::getKeyword(const String& keyword) const {
1248 0 : ThrowIf(itsTable.isNull(), "A table is not attached to this ComponentList");
1249 0 : TableProxy tp(itsTable);
1250 0 : auto value = tp.getKeyword(String(), keyword, -1);
1251 0 : return fromValueHolder(value);
1252 0 : }
1253 :
1254 : } //# NAMESPACE CASA - END
1255 :
|