//# SpectralElement.cc: Describes (a set of related) spectral lines //# Copyright (C) 2001,2004 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# #include #include #include #include #include #include #include namespace casa { //# NAMESPACE CASA - BEGIN #define _ORIGIN String("GaussianMultipletSpectralElement::") + __FUNCTION__ + ":" + String::toString(__LINE__) + ": " GaussianMultipletSpectralElement::GaussianMultipletSpectralElement( const vector& estimates, const Matrix& constraints ) : CompiledSpectralElement(SpectralElement::GMULTIPLET), _gaussians(estimates),_constraints(constraints), _paramIndices(estimates.size(), 3, 0) { if(estimates.size() != constraints.nrow()+1) { throw AipsError( _ORIGIN + "Mismatch between size of estimates and constraints" ); } if (constraints.ncolumn() != 3) { throw AipsError(_ORIGIN + "constraints does not have 3 columns"); } Matrix fixed(LogicalArray(constraints != 0.0)); for (uInt i=1; i parm(3 + nfalse(fixed), 0); Vector errs = parm.copy(); parm[0] = _gaussians[0].getAmpl(); parm[1] = _gaussians[0].getCenter(); parm[2] = _gaussians[0].getSigma(); errs[0] = _gaussians[0].getAmplErr(); errs[1] = _gaussians[0].getCenterErr(); errs[2] = _gaussians[0].getSigmaErr(); Vector f(parm.size(), True); f[0] = _gaussians[0].fixedAmpl(); f[1] = _gaussians[0].fixedCenter(); f[2] = _gaussians[0].fixedSigma(); _paramIndices(0, 0) = 0; _paramIndices(0, 1) = 1; _paramIndices(0, 2) = 2; uInt p = 3; for (uInt i=0; i(_gaussians) == Vector(other._gaussians)) && allTrue(_constraints == other._constraints) ); } const vector& GaussianMultipletSpectralElement::getGaussians() const { return _gaussians; } const Matrix& GaussianMultipletSpectralElement::getConstraints() const { return _constraints; } Bool GaussianMultipletSpectralElement::toRecord(RecordInterface& out) const { out.define(RecordFieldId("type"), fromType(getType())); Record gaussians; for (uInt i=0; i<_gaussians.size(); i++) { Record gaussian; _gaussians[i].toRecord(gaussian); gaussians.defineRecord( "*" + String::toString(i), gaussian ); } out.defineRecord("gaussians", gaussians); out.define("fixedMatrix", _constraints); return True; } void GaussianMultipletSpectralElement::set(const Vector& param) { if (get().size() > 0 && param.size() != get().size()) { ostringstream x; x << _ORIGIN << "Inconsistent number of parameters. Got " << param.size() << ". Must be " << get().size(); throw AipsError(x.str()); } SpectralElement::_set(param); Double amp0 = param[0]; Double center0 = param[1]; Double sigma0 = param[2]; _gaussians[0].setAmpl(amp0); _gaussians[0].setCenter(center0); _gaussians[0].setSigma(sigma0); uInt p = 3; for (uInt i=3; i<_paramIndices.size(); i++) { uInt gNumber = i/3; uInt pNumber = i%3; uInt pIndex = _paramIndices(gNumber, pNumber); Double fRel = _constraints(gNumber-1, pNumber); if (pNumber == 0) { Double amp = pIndex == 0 ? fRel*amp0 : param[p]; _gaussians[gNumber].setAmpl(amp); } else if (pNumber == 1) { Double center = pIndex == 0 ? fRel+center0 : param[p]; _gaussians[gNumber].setCenter(center); } else if (pNumber == 2) { Double sigma = pIndex == 0 ? fRel*sigma0 : param[p]; _gaussians[gNumber].setSigma(sigma); } if (pIndex > 0) { p++; } } } void GaussianMultipletSpectralElement::setError(const Vector &err) { SpectralElement::setError(err); Double amp0 = err[0]; Double center0 = err[1]; Double sigma0 = err[2]; Vector errors(3); errors[0] = err[0]; errors[1] = err[1]; errors[2] = err[2]; _gaussians[0].setError(errors); uInt p = 3; for (uInt i=3; i<_paramIndices.size(); i++) { uInt gNumber = i/3; uInt pNumber = i%3; uInt pIndex = _paramIndices(gNumber, pNumber); Double fRel = _constraints(gNumber-1, pNumber); if (pNumber == 0) { errors[0] = pIndex == 0 ? fRel*amp0 : err[p]; } else if (pNumber == 1) { errors[1] = pIndex == 0 ? center0 : err[p]; } else if (pNumber == 2) { errors[2] = pIndex == 0 ? fRel*sigma0 : err[p]; } _gaussians[gNumber].setError(errors); if (pIndex > 0) { p++; } } } void GaussianMultipletSpectralElement::fix(const Vector& fix) { SpectralElement::fix(fix); Bool amp0 = fix[0]; Bool center0 = fix[1]; Bool sigma0 = fix[2]; Vector fixed(3); fixed[0] = fix[0]; fixed[1] = fix[1]; fixed[2] = fix[2]; _gaussians[0].fix(fixed); uInt p = 3; for (uInt i=3; i<_paramIndices.size(); i++) { uInt gNumber = i/3; uInt pNumber = i%3; uInt pIndex = _paramIndices(gNumber, pNumber); if (pNumber == 0) { fixed[0] = pIndex == 0 ? amp0 : fix[p]; } else if (pNumber == 1) { fixed[1] = pIndex == 0 ? center0 : fix[p]; } else if (pNumber == 2) { fixed[2] = pIndex == 0 ? sigma0 : fix[p]; } _gaussians[gNumber].fix(fixed); if (pIndex > 0) { p++; } } } ostream &operator<<(ostream& os, const GaussianMultipletSpectralElement& elem) { os << SpectralElement::fromType((elem.getType())) << " element: " << endl; os << " Function: " << elem.getFunction() << endl; os << " Gaussians:" << endl; Vector gaussians = elem.getGaussians(); for (uInt i=0; i r = elem.getConstraints(); os << "Constraints: " << endl; for (uInt i=1; i