Line data Source code
1 : //# SpectralList.cc: A set of SpectralElements 2 : //# Copyright (C) 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: SpectralList.cc 21024 2011-03-01 11:46:18Z gervandiepen $ 27 : 28 : //# Includes 29 : #include <components/SpectralComponents/SpectralList.h> 30 : 31 : #include <casacore/casa/Exceptions/Error.h> 32 : #include <casacore/casa/Containers/RecordInterface.h> 33 : #include <casacore/casa/Containers/Record.h> 34 : #include <components/SpectralComponents/GaussianSpectralElement.h> 35 : #include <memory> 36 : #include <components/SpectralComponents/SpectralElementFactory.h> 37 : 38 : #include <iostream> 39 : 40 : using namespace casacore; 41 : namespace casa { //# NAMESPACE CASA - BEGIN 42 : 43 : //# Constructors 44 1075168 : SpectralList::SpectralList() : 45 1075168 : nmax_p(0), list_p(0) {} 46 : 47 562067 : SpectralList::SpectralList(uInt nmax) : 48 562067 : nmax_p(nmax), list_p(0) { 49 562067 : } 50 : 51 0 : SpectralList::SpectralList(const SpectralElement &in) : 52 0 : nmax_p(0), list_p(1) { 53 0 : list_p[0] = in.clone(); 54 0 : } 55 : 56 645744 : SpectralList::SpectralList(const SpectralList &other) : 57 645744 : nmax_p(other.nmax_p), list_p(other.list_p.nelements()) { 58 1403468 : for (uInt i=0; i<list_p.nelements(); i++) { 59 757724 : list_p[i] = other.list_p[i]->clone(); 60 : } 61 645744 : } 62 : 63 2282979 : SpectralList::~SpectralList() { 64 2282979 : clear(); 65 2282979 : } 66 : 67 2178244 : SpectralList &SpectralList::operator=(const SpectralList &other) { 68 2178244 : if (this != &other) { 69 1632474 : clear(); 70 1632474 : nmax_p = other.nmax_p; 71 1632474 : list_p.resize(other.list_p.nelements()); 72 2184581 : for (uInt i=0; i<list_p.nelements(); i++) { 73 552107 : list_p[i] = other.list_p[i]->clone(); 74 : } 75 : } 76 2178244 : return *this; 77 : } 78 : 79 0 : Double SpectralList::operator()(const Double x) const { 80 0 : Double s(0); 81 0 : for (uInt i=0; i<list_p.nelements(); i++) s += (*list_p[i])(x); 82 0 : return s; 83 : } 84 : 85 593860 : const SpectralElement* SpectralList::operator[](const uInt n) const { 86 593860 : if (n >= list_p.nelements()) { 87 0 : throw(AipsError("SpectralList: Illegal index for element")); 88 : } 89 593860 : return list_p[n]; 90 : } 91 : 92 2954304 : SpectralElement* SpectralList::operator[](const uInt n) { 93 2954304 : if (n >= list_p.nelements()) { 94 0 : throw(AipsError("SpectralList: Illegal index for element")); 95 : } 96 2954304 : return list_p[n]; 97 : } 98 : 99 1155040 : Bool SpectralList::add(const SpectralElement &in) { 100 1155040 : uInt i = list_p.nelements(); 101 1155040 : if (nmax_p != 0 && i >= nmax_p) return false; 102 1144691 : list_p.resize(i+1); 103 1144691 : list_p[i] = in.clone(); 104 1144691 : return true; 105 : } 106 : 107 561848 : Bool SpectralList::add(const SpectralList &in) { 108 1155693 : for (uInt i=0; i<in.nelements(); i++) { 109 593845 : if (! add(*in[i])) { 110 0 : return false; 111 : } 112 : } 113 561848 : return true; 114 : } 115 : 116 54925 : void SpectralList::insert(const SpectralElement &in) { 117 54925 : uInt n = list_p.nelements(); 118 : uInt i; 119 86995 : for (i=0; i<n; i++) { 120 54845 : if (compar(in, *list_p[i]) > 0) { 121 22775 : break; 122 : } 123 : } 124 54925 : if (i == n) add(in); 125 : else { 126 22775 : if (nmax_p != 0 && n >= nmax_p) { 127 12655 : delete list_p[n-1]; list_p[n-1] = 0; 128 : } else { 129 10120 : list_p.resize(n+1); 130 10120 : list_p[n++] = 0; 131 : } 132 39815 : for (uInt j=n-1; j>i; j--) list_p[j] = list_p[j-1]; 133 22775 : if (in.getType() == SpectralElement::GAUSSIAN) { 134 22775 : const GaussianSpectralElement *gIn = dynamic_cast<const GaussianSpectralElement *>(&in); 135 22775 : list_p[i] = new GaussianSpectralElement(*gIn); 136 : } 137 : else { 138 : // FIXME for other subclasses 139 0 : list_p[i] = in.clone(); 140 : } 141 : } 142 54925 : } 143 : 144 0 : void SpectralList::insert(const SpectralList &in) { 145 0 : for (uInt i=0; i<in.nelements(); i++) { 146 0 : insert(*in[i]); 147 : } 148 0 : } 149 : 150 31921 : Bool SpectralList::set(const SpectralElement &in, const uInt which) { 151 31921 : uInt i = list_p.nelements(); 152 31921 : if (nmax_p != 0 && which >= nmax_p) return false; 153 31921 : if (which > i) return false; 154 31921 : if (which == i) add(in); 155 31921 : delete list_p[which]; list_p[which] = 0; 156 31921 : list_p[which] = in.clone(); 157 31921 : return true; 158 : } 159 : 160 5022985 : void SpectralList::clear() { 161 7487627 : for (uInt i=0; i<list_p.nelements(); i++) { 162 2464642 : delete list_p[i]; list_p[i] = 0; 163 : } 164 5022985 : list_p.resize(0, true); 165 5022985 : } 166 : 167 0 : void SpectralList::set(const uInt nmax) { 168 0 : if (nmax != 0 && nmax < list_p.nelements()) { 169 0 : for (uInt i=nmax; i<list_p.nelements(); i++) { 170 0 : delete list_p[i]; list_p[i] = 0; 171 : } 172 0 : list_p.resize(nmax, true); 173 : } 174 0 : nmax_p = nmax; 175 0 : } 176 : 177 0 : Bool SpectralList::fromRecord (String& errMsg, const RecordInterface& container) 178 : { 179 0 : clear(); 180 0 : for (uInt i=0; i<container.nfields(); i++) { 181 0 : if (container.dataType(i)==TpRecord) { 182 0 : const RecordInterface& rec = container.asRecord(i); 183 0 : std::unique_ptr<SpectralElement> specEl(SpectralElementFactory::fromRecord(rec)); 184 0 : add(*specEl); 185 : } else { 186 0 : errMsg = String("Illegal record structure"); 187 0 : return false; 188 : } 189 : } 190 0 : return true; 191 : } 192 : 193 0 : Bool SpectralList::toRecord(RecordInterface& container) const { 194 0 : String errMsg; 195 0 : for (uInt i=0; i<list_p.nelements(); i++) { 196 0 : Record elRec; 197 0 : list_p[i]->toRecord(elRec); 198 0 : container.defineRecord(i, elRec); 199 : } 200 0 : return true; 201 : } 202 : 203 : 204 0 : void SpectralList::sort() { 205 0 : uInt n = list_p.nelements(); 206 0 : if (n < 2) return; 207 : SpectralElement *x; 208 0 : for (uInt i=0; i<n-1; i++) { 209 0 : for (uInt j=n-1; j>i; j--) { 210 0 : if (compar(*list_p[j-1], *list_p[j]) < 0) { 211 0 : x = list_p[j-1]; 212 0 : list_p[j-1] = list_p[j]; 213 0 : list_p[j] = x; 214 : } 215 : } 216 : } 217 : } 218 : 219 54845 : Int SpectralList::compar( 220 : const SpectralElement &p1, 221 : const SpectralElement &p2 222 : ) const { 223 54845 : SpectralElement::Types p1Type = p1.getType(); 224 54845 : SpectralElement::Types p2Type = p2.getType(); 225 54845 : Double p1Amp = 0; 226 54845 : Double p2Amp = 0; 227 54845 : if (p1Type == SpectralElement::GAUSSIAN) { 228 54845 : const GaussianSpectralElement *g1 = dynamic_cast<const GaussianSpectralElement *>(&p1); 229 54845 : p1Amp = g1->getAmpl(); 230 : } 231 54845 : if (p2Type == SpectralElement::GAUSSIAN) { 232 54845 : const GaussianSpectralElement *g2 = dynamic_cast<const GaussianSpectralElement *>(&p2); 233 54845 : p2Amp = g2->getAmpl(); 234 : } 235 54845 : if (p1Amp > p2Amp) { 236 22775 : return 1; 237 : } 238 32070 : else if (p1Amp < p2Amp) { 239 32043 : return -1; 240 : } 241 : else { 242 27 : return 0; 243 : } 244 : } 245 : 246 0 : ostream &operator<<(ostream &os, const SpectralList &lst) { 247 0 : os << lst.nelements() << " in SpectralList:" << endl; 248 0 : for (uInt i=0; i<lst.nelements(); i++) os << *lst[i]; 249 : 250 0 : return os; 251 : } 252 : 253 : } //# NAMESPACE CASA - END 254 : 255 : 256 : //# Cater for Double and Float 257 : #ifdef AIPS_NO_TEMPLATE_SRC 258 : #include <components/SpectralComponents/SpectralList2.tcc> 259 : 260 : using namespace casacore; 261 : namespace casa { //# NAMESPACE CASA - BEGIN 262 : template void SpectralList::residual<Double>(Vector<Double> &) const; 263 : template void SpectralList::residual<Float>(Vector<Float> &) const; 264 : template void SpectralList::evaluate<Double>(Vector<Double> &) const; 265 : template void SpectralList::evaluate<Float>(Vector<Float> &) const; 266 : template void SpectralList::residual<Double>(Vector<Double> &, 267 : Vector<Double> const &) const; 268 : template void SpectralList::residual<Float>(Vector<Float> &, 269 : Vector<Float> const &) const; 270 : template void SpectralList::evaluate<Double>(Vector<Double> &, 271 : Vector<Double> const &) const; 272 : template void SpectralList::evaluate<Float>(Vector<Float> &, 273 : Vector<Float> const &) const; 274 : } //# NAMESPACE CASA - END 275 : #endif