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